From ef054b321c0af3c6b818e3372e7c0dfb1c22d8e2 Mon Sep 17 00:00:00 2001 From: Rumps Date: Fri, 13 Jan 2017 17:07:01 +0000 Subject: [PATCH] Begin reformatting --- css/reset.css | 94 +- front-page.php | 226 +- page-experience-by-companies.php | 130 +- page-experience.php | 182 +- .../easy-footnotes/assets/qtip/jquery.qtip.js | 6808 ++++++++--------- plugins/jetpack/changelog.txt | 3574 ++++----- plugins/jetpack/images/connect-plug.svg | 38 +- .../images/connection-landing/long-clouds.svg | 76 +- .../images/connection-landing/stars-left.svg | 344 +- .../images/connection-landing/stars-right.svg | 344 +- .../images/connection-landing/stat-bars.svg | 250 +- plugins/jetpack/images/download-arrow.svg | 20 +- plugins/jetpack/images/jetpack-logo.svg | 54 +- .../jetpack/images/jetpack-protect-shield.svg | 60 +- plugins/jetpack/images/new-badge.svg | 20 +- plugins/jetpack/images/rocketeer.svg | 28 +- plugins/jetpack/images/the-cloud-sm.svg | 60 +- plugins/jetpack/images/the-cloud.svg | 32 +- plugins/jetpack/images/the-footcloud.svg | 18 +- plugins/jetpack/images/the-undercloud.svg | 26 +- plugins/jetpack/modules/module-headings.php | 610 +- .../jetpack/modules/sitemaps/sitemap-xsl.php | 288 +- plugins/jetpack/readme.txt | 1028 +-- style.css | 267 +- taxonomy-company.php | 286 +- template-parts/.content-single.php.swp | Bin 12288 -> 12296 bytes template-parts/content.php | 2 +- 27 files changed, 7408 insertions(+), 7457 deletions(-) diff --git a/css/reset.css b/css/reset.css index e9e771a..102a235 100644 --- a/css/reset.css +++ b/css/reset.css @@ -1,48 +1,48 @@ -/* http://meyerweb.com/eric/tools/css/reset/ - v2.0 | 20110126 - License: none (public domain) -*/ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; } \ No newline at end of file diff --git a/front-page.php b/front-page.php index cdb23da..d469074 100644 --- a/front-page.php +++ b/front-page.php @@ -1,110 +1,116 @@ - - class="no-js"> - - - - - - - - - - > -
-
-
-
-
- A picture of Ben Goldsworthy -
-
- -
-
- -
-
-
-
Portfolios
- -
-
-
-
-
Experience
- -
-
-
- -
-
-
-
    -
  • -
  • -
  • -
  • -
  • -
-
-
-
-
- - + + class="no-js"> + + + + + + + + + + > +
+
+
+
+
+ A picture of Ben Goldsworthy +
+
+ +
+ +
+
+

Personal

+ +
+
+ +
+
+

Portfolios

+ +
+
+ +
+
+

Experience

+ +
+
+ +
+ +
+ +
+
+ + diff --git a/page-experience-by-companies.php b/page-experience-by-companies.php index 4459b31..49b674b 100644 --- a/page-experience-by-companies.php +++ b/page-experience-by-companies.php @@ -1,65 +1,65 @@ - - $endDate) ? $endDate : $jEDate); - return (((strtotime($jSDate) < strtotime($endDate)) && (strtotime($jSDate) > strtotime($startDate))) && (strtotime($jEDate) > strtotime($startDate))); - } - - $loop = new WP_Query( $args ); - ?> -

Experience

by company

- false, 'taxonomy' => 'company', 'term_args' => array('parent' => 0))); - if ( ! empty( $terms ) ) { - echo "
"; - echo ""; - echo "
"; - } - ?> - - - - -
- - - + + $endDate) ? $endDate : $jEDate); + return (((strtotime($jSDate) < strtotime($endDate)) && (strtotime($jSDate) > strtotime($startDate))) && (strtotime($jEDate) > strtotime($startDate))); + } + + $loop = new WP_Query( $args ); + ?> +

Experience

by company

+ false, 'taxonomy' => 'company', 'term_args' => array('parent' => 0))); + if ( ! empty( $terms ) ) { + echo "
"; + echo ""; + echo "
"; + } + ?> + + + + +
+ + + diff --git a/page-experience.php b/page-experience.php index c395fb2..d10c7a9 100644 --- a/page-experience.php +++ b/page-experience.php @@ -1,91 +1,91 @@ - - $endDate) ? $endDate : $jEDate); - return (((strtotime($jSDate) < strtotime($endDate)) && (strtotime($jSDate) > strtotime($startDate))) && (strtotime($jEDate) > strtotime($startDate))); - } - - $args= array( - 'post_type' => array( 'job' ), - 'posts_per_page' => -1 - ); - - $loop = new WP_Query( $args ); - ?> -
', '' ); ?>
- false, 'taxonomy' => 'company')); - if ( ! empty( $terms ) ) { - print ''; - } - */?> - - - - - - -
-
- - - + + $endDate) ? $endDate : $jEDate); + return (((strtotime($jSDate) < strtotime($endDate)) && (strtotime($jSDate) > strtotime($startDate))) && (strtotime($jEDate) > strtotime($startDate))); + } + + $args= array( + 'post_type' => array( 'job' ), + 'posts_per_page' => -1 + ); + + $loop = new WP_Query( $args ); + ?> +
', '' ); ?>
+ false, 'taxonomy' => 'company')); + if ( ! empty( $terms ) ) { + print '
'; + } + */?> + + + + + + +
+
+ + + diff --git a/plugins/easy-footnotes/assets/qtip/jquery.qtip.js b/plugins/easy-footnotes/assets/qtip/jquery.qtip.js index fd25dc1..b2c460e 100644 --- a/plugins/easy-footnotes/assets/qtip/jquery.qtip.js +++ b/plugins/easy-footnotes/assets/qtip/jquery.qtip.js @@ -1,3451 +1,3451 @@ -/* - * qTip2 - Pretty powerful tooltips - v2.2.1 - * http://qtip2.com - * - * Copyright (c) 2014 - * Released under the MIT licenses - * http://jquery.org/license - * - * Date: Sat Sep 6 2014 06:25 EDT-0400 - * Plugins: tips viewport imagemap svg modal ie6 - * Styles: core basic css3 - */ -/*global window: false, jQuery: false, console: false, define: false */ - -/* Cache window, document, undefined */ -(function( window, document, undefined ) { - -// Uses AMD or browser globals to create a jQuery plugin. -(function( factory ) { - "use strict"; - if(typeof define === 'function' && define.amd) { - define(['jquery'], factory); - } - else if(jQuery && !jQuery.fn.qtip) { - factory(jQuery); - } -} -(function($) { - "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ -;// Munge the primitives - Paul Irish tip -var TRUE = true, -FALSE = false, -NULL = null, - -// Common variables -X = 'x', Y = 'y', -WIDTH = 'width', -HEIGHT = 'height', - -// Positioning sides -TOP = 'top', -LEFT = 'left', -BOTTOM = 'bottom', -RIGHT = 'right', -CENTER = 'center', - -// Position adjustment types -FLIP = 'flip', -FLIPINVERT = 'flipinvert', -SHIFT = 'shift', - -// Shortcut vars -QTIP, PROTOTYPE, CORNER, CHECKS, -PLUGINS = {}, -NAMESPACE = 'qtip', -ATTR_HAS = 'data-hasqtip', -ATTR_ID = 'data-qtip-id', -WIDGET = ['ui-widget', 'ui-tooltip'], -SELECTOR = '.'+NAMESPACE, -INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '), - -CLASS_FIXED = NAMESPACE+'-fixed', -CLASS_DEFAULT = NAMESPACE + '-default', -CLASS_FOCUS = NAMESPACE + '-focus', -CLASS_HOVER = NAMESPACE + '-hover', -CLASS_DISABLED = NAMESPACE+'-disabled', - -replaceSuffix = '_replacedByqTip', -oldtitle = 'oldtitle', -trackingBound, - -// Browser detection -BROWSER = { - /* - * IE version detection - * - * Adapted from: http://ajaxian.com/archives/attack-of-the-ie-conditional-comment - * Credit to James Padolsey for the original implemntation! - */ - ie: (function(){ - for ( - var v = 4, i = document.createElement("div"); - (i.innerHTML = "") && i.getElementsByTagName("i")[0]; - v+=1 - ) {} - return v > 4 ? v : NaN; - }()), - - /* - * iOS version detection - */ - iOS: parseFloat( - ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1]) - .replace('undefined', '3_2').replace('_', '.').replace('_', '') - ) || FALSE -}; -;function QTip(target, options, id, attr) { - // Elements and ID - this.id = id; - this.target = target; - this.tooltip = NULL; - this.elements = { target: target }; +/* + * qTip2 - Pretty powerful tooltips - v2.2.1 + * http://qtip2.com + * + * Copyright (c) 2014 + * Released under the MIT licenses + * http://jquery.org/license + * + * Date: Sat Sep 6 2014 06:25 EDT-0400 + * Plugins: tips viewport imagemap svg modal ie6 + * Styles: core basic css3 + */ +/*global window: false, jQuery: false, console: false, define: false */ - // Internal constructs - this._id = NAMESPACE + '-' + id; - this.timers = { img: {} }; - this.options = options; - this.plugins = {}; +/* Cache window, document, undefined */ +(function( window, document, undefined ) { - // Cache object - this.cache = { - event: {}, - target: $(), - disabled: FALSE, - attr: attr, - onTooltip: FALSE, - lastClass: '' - }; - - // Set the initial flags - this.rendered = this.destroyed = this.disabled = this.waiting = - this.hiddenDuringWait = this.positioning = this.triggering = FALSE; +// Uses AMD or browser globals to create a jQuery plugin. +(function( factory ) { + "use strict"; + if(typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } + else if(jQuery && !jQuery.fn.qtip) { + factory(jQuery); + } } -PROTOTYPE = QTip.prototype; +(function($) { + "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ +;// Munge the primitives - Paul Irish tip +var TRUE = true, +FALSE = false, +NULL = null, -PROTOTYPE._when = function(deferreds) { - return $.when.apply($, deferreds); +// Common variables +X = 'x', Y = 'y', +WIDTH = 'width', +HEIGHT = 'height', + +// Positioning sides +TOP = 'top', +LEFT = 'left', +BOTTOM = 'bottom', +RIGHT = 'right', +CENTER = 'center', + +// Position adjustment types +FLIP = 'flip', +FLIPINVERT = 'flipinvert', +SHIFT = 'shift', + +// Shortcut vars +QTIP, PROTOTYPE, CORNER, CHECKS, +PLUGINS = {}, +NAMESPACE = 'qtip', +ATTR_HAS = 'data-hasqtip', +ATTR_ID = 'data-qtip-id', +WIDGET = ['ui-widget', 'ui-tooltip'], +SELECTOR = '.'+NAMESPACE, +INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '), + +CLASS_FIXED = NAMESPACE+'-fixed', +CLASS_DEFAULT = NAMESPACE + '-default', +CLASS_FOCUS = NAMESPACE + '-focus', +CLASS_HOVER = NAMESPACE + '-hover', +CLASS_DISABLED = NAMESPACE+'-disabled', + +replaceSuffix = '_replacedByqTip', +oldtitle = 'oldtitle', +trackingBound, + +// Browser detection +BROWSER = { + /* + * IE version detection + * + * Adapted from: http://ajaxian.com/archives/attack-of-the-ie-conditional-comment + * Credit to James Padolsey for the original implemntation! + */ + ie: (function(){ + for ( + var v = 4, i = document.createElement("div"); + (i.innerHTML = "") && i.getElementsByTagName("i")[0]; + v+=1 + ) {} + return v > 4 ? v : NaN; + }()), + + /* + * iOS version detection + */ + iOS: parseFloat( + ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1]) + .replace('undefined', '3_2').replace('_', '.').replace('_', '') + ) || FALSE +}; +;function QTip(target, options, id, attr) { + // Elements and ID + this.id = id; + this.target = target; + this.tooltip = NULL; + this.elements = { target: target }; + + // Internal constructs + this._id = NAMESPACE + '-' + id; + this.timers = { img: {} }; + this.options = options; + this.plugins = {}; + + // Cache object + this.cache = { + event: {}, + target: $(), + disabled: FALSE, + attr: attr, + onTooltip: FALSE, + lastClass: '' + }; + + // Set the initial flags + this.rendered = this.destroyed = this.disabled = this.waiting = + this.hiddenDuringWait = this.positioning = this.triggering = FALSE; +} +PROTOTYPE = QTip.prototype; + +PROTOTYPE._when = function(deferreds) { + return $.when.apply($, deferreds); +}; + +PROTOTYPE.render = function(show) { + if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit + + var self = this, + options = this.options, + cache = this.cache, + elements = this.elements, + text = options.content.text, + title = options.content.title, + button = options.content.button, + posOptions = options.position, + namespace = '.'+this._id+' ', + deferreds = [], + tooltip; + + // Add ARIA attributes to target + $.attr(this.target[0], 'aria-describedby', this._id); + + // Create public position object that tracks current position corners + cache.posClass = this._createPosClass( + (this.position = { my: posOptions.my, at: posOptions.at }).my + ); + + // Create tooltip element + this.tooltip = elements.tooltip = tooltip = $('
', { + 'id': this._id, + 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, cache.posClass ].join(' '), + 'width': options.style.width || '', + 'height': options.style.height || '', + 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse, + + /* ARIA specific attributes */ + 'role': 'alert', + 'aria-live': 'polite', + 'aria-atomic': FALSE, + 'aria-describedby': this._id + '-content', + 'aria-hidden': TRUE + }) + .toggleClass(CLASS_DISABLED, this.disabled) + .attr(ATTR_ID, this.id) + .data(NAMESPACE, this) + .appendTo(posOptions.container) + .append( + // Create content element + elements.content = $('
', { + 'class': NAMESPACE + '-content', + 'id': this._id + '-content', + 'aria-atomic': TRUE + }) + ); + + // Set rendered flag and prevent redundant reposition calls for now + this.rendered = -1; + this.positioning = TRUE; + + // Create title... + if(title) { + this._createTitle(); + + // Update title only if its not a callback (called in toggle if so) + if(!$.isFunction(title)) { + deferreds.push( this._updateTitle(title, FALSE) ); + } + } + + // Create button + if(button) { this._createButton(); } + + // Set proper rendered flag and update content if not a callback function (called in toggle) + if(!$.isFunction(text)) { + deferreds.push( this._updateContent(text, FALSE) ); + } + this.rendered = TRUE; + + // Setup widget classes + this._setWidget(); + + // Initialize 'render' plugins + $.each(PLUGINS, function(name) { + var instance; + if(this.initialize === 'render' && (instance = this(self))) { + self.plugins[name] = instance; + } + }); + + // Unassign initial events and assign proper events + this._unassignEvents(); + this._assignEvents(); + + // When deferreds have completed + this._when(deferreds).then(function() { + // tooltiprender event + self._trigger('render'); + + // Reset flags + self.positioning = FALSE; + + // Show tooltip if not hidden during wait period + if(!self.hiddenDuringWait && (options.show.ready || show)) { + self.toggle(TRUE, cache.event, FALSE); + } + self.hiddenDuringWait = FALSE; + }); + + // Expose API + QTIP.api[this.id] = this; + + return this; +}; + +PROTOTYPE.destroy = function(immediate) { + // Set flag the signify destroy is taking place to plugins + // and ensure it only gets destroyed once! + if(this.destroyed) { return this.target; } + + function process() { + if(this.destroyed) { return; } + this.destroyed = TRUE; + + var target = this.target, + title = target.attr(oldtitle), + timer; + + // Destroy tooltip if rendered + if(this.rendered) { + this.tooltip.stop(1,0).find('*').remove().end().remove(); + } + + // Destroy all plugins + $.each(this.plugins, function(name) { + this.destroy && this.destroy(); + }); + + // Clear timers + for(timer in this.timers) { + clearTimeout(this.timers[timer]); + } + + // Remove api object and ARIA attributes + target.removeData(NAMESPACE) + .removeAttr(ATTR_ID) + .removeAttr(ATTR_HAS) + .removeAttr('aria-describedby'); + + // Reset old title attribute if removed + if(this.options.suppress && title) { + target.attr('title', title).removeAttr(oldtitle); + } + + // Remove qTip events associated with this API + this._unassignEvents(); + + // Remove ID from used id objects, and delete object references + // for better garbage collection and leak protection + this.options = this.elements = this.cache = this.timers = + this.plugins = this.mouse = NULL; + + // Delete epoxsed API object + delete QTIP.api[this.id]; + } + + // If an immediate destory is needed + if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) { + this.tooltip.one('tooltiphidden', $.proxy(process, this)); + !this.triggering && this.hide(); + } + + // If we're not in the process of hiding... process + else { process.call(this); } + + return this.target; +}; +;function invalidOpt(a) { + return a === NULL || $.type(a) !== 'object'; +} + +function invalidContent(c) { + return !( $.isFunction(c) || (c && c.attr) || c.length || ($.type(c) === 'object' && (c.jquery || c.then) )); +} + +// Option object sanitizer +function sanitizeOptions(opts) { + var content, text, ajax, once; + + if(invalidOpt(opts)) { return FALSE; } + + if(invalidOpt(opts.metadata)) { + opts.metadata = { type: opts.metadata }; + } + + if('content' in opts) { + content = opts.content; + + if(invalidOpt(content) || content.jquery || content.done) { + content = opts.content = { + text: (text = invalidContent(content) ? FALSE : content) + }; + } + else { text = content.text; } + + // DEPRECATED - Old content.ajax plugin functionality + // Converts it into the proper Deferred syntax + if('ajax' in content) { + ajax = content.ajax; + once = ajax && ajax.once !== FALSE; + delete content.ajax; + + content.text = function(event, api) { + var loading = text || $(this).attr(api.options.content.attr) || 'Loading...', + + deferred = $.ajax( + $.extend({}, ajax, { context: api }) + ) + .then(ajax.success, NULL, ajax.error) + .then(function(content) { + if(content && once) { api.set('content.text', content); } + return content; + }, + function(xhr, status, error) { + if(api.destroyed || xhr.status === 0) { return; } + api.set('content.text', status + ': ' + error); + }); + + return !once ? (api.set('content.text', loading), deferred) : loading; + }; + } + + if('title' in content) { + if($.isPlainObject(content.title)) { + content.button = content.title.button; + content.title = content.title.text; + } + + if(invalidContent(content.title || FALSE)) { + content.title = FALSE; + } + } + } + + if('position' in opts && invalidOpt(opts.position)) { + opts.position = { my: opts.position, at: opts.position }; + } + + if('show' in opts && invalidOpt(opts.show)) { + opts.show = opts.show.jquery ? { target: opts.show } : + opts.show === TRUE ? { ready: TRUE } : { event: opts.show }; + } + + if('hide' in opts && invalidOpt(opts.hide)) { + opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide }; + } + + if('style' in opts && invalidOpt(opts.style)) { + opts.style = { classes: opts.style }; + } + + // Sanitize plugin options + $.each(PLUGINS, function() { + this.sanitize && this.sanitize(opts); + }); + + return opts; +} + +// Setup builtin .set() option checks +CHECKS = PROTOTYPE.checks = { + builtin: { + // Core checks + '^id$': function(obj, o, v, prev) { + var id = v === TRUE ? QTIP.nextid : v, + new_id = NAMESPACE + '-' + id; + + if(id !== FALSE && id.length > 0 && !$('#'+new_id).length) { + this._id = new_id; + + if(this.rendered) { + this.tooltip[0].id = this._id; + this.elements.content[0].id = this._id + '-content'; + this.elements.title[0].id = this._id + '-title'; + } + } + else { obj[o] = prev; } + }, + '^prerender': function(obj, o, v) { + v && !this.rendered && this.render(this.options.show.ready); + }, + + // Content checks + '^content.text$': function(obj, o, v) { + this._updateContent(v); + }, + '^content.attr$': function(obj, o, v, prev) { + if(this.options.content.text === this.target.attr(prev)) { + this._updateContent( this.target.attr(v) ); + } + }, + '^content.title$': function(obj, o, v) { + // Remove title if content is null + if(!v) { return this._removeTitle(); } + + // If title isn't already created, create it now and update + v && !this.elements.title && this._createTitle(); + this._updateTitle(v); + }, + '^content.button$': function(obj, o, v) { + this._updateButton(v); + }, + '^content.title.(text|button)$': function(obj, o, v) { + this.set('content.'+o, v); // Backwards title.text/button compat + }, + + // Position checks + '^position.(my|at)$': function(obj, o, v){ + 'string' === typeof v && (this.position[o] = obj[o] = new CORNER(v, o === 'at')); + }, + '^position.container$': function(obj, o, v){ + this.rendered && this.tooltip.appendTo(v); + }, + + // Show checks + '^show.ready$': function(obj, o, v) { + v && (!this.rendered && this.render(TRUE) || this.toggle(TRUE)); + }, + + // Style checks + '^style.classes$': function(obj, o, v, p) { + this.rendered && this.tooltip.removeClass(p).addClass(v); + }, + '^style.(width|height)': function(obj, o, v) { + this.rendered && this.tooltip.css(o, v); + }, + '^style.widget|content.title': function() { + this.rendered && this._setWidget(); + }, + '^style.def': function(obj, o, v) { + this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v); + }, + + // Events check + '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) { + this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v); + }, + + // Properties which require event reassignment + '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() { + if(!this.rendered) { return; } + + // Set tracking flag + var posOptions = this.options.position; + this.tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse); + + // Reassign events + this._unassignEvents(); + this._assignEvents(); + } + } }; -PROTOTYPE.render = function(show) { - if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit +// Dot notation converter +function convertNotation(options, notation) { + var i = 0, obj, option = options, - var self = this, + // Split notation into array + levels = notation.split('.'); + + // Loop through + while( option = option[ levels[i++] ] ) { + if(i < levels.length) { obj = option; } + } + + return [obj || options, levels.pop()]; +} + +PROTOTYPE.get = function(notation) { + if(this.destroyed) { return this; } + + var o = convertNotation(this.options, notation.toLowerCase()), + result = o[0][ o[1] ]; + + return result.precedance ? result.string() : result; +}; + +function setCallback(notation, args) { + var category, rule, match; + + for(category in this.checks) { + for(rule in this.checks[category]) { + if(match = (new RegExp(rule, 'i')).exec(notation)) { + args.push(match); + + if(category === 'builtin' || this.plugins[category]) { + this.checks[category][rule].apply( + this.plugins[category] || this, args + ); + } + } + } + } +} + +var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i, + rrender = /^prerender|show\.ready/i; + +PROTOTYPE.set = function(option, value) { + if(this.destroyed) { return this; } + + var rendered = this.rendered, + reposition = FALSE, options = this.options, - cache = this.cache, - elements = this.elements, - text = options.content.text, - title = options.content.title, - button = options.content.button, - posOptions = options.position, - namespace = '.'+this._id+' ', - deferreds = [], - tooltip; + checks = this.checks, + name; - // Add ARIA attributes to target - $.attr(this.target[0], 'aria-describedby', this._id); + // Convert singular option/value pair into object form + if('string' === typeof option) { + name = option; option = {}; option[name] = value; + } + else { option = $.extend({}, option); } - // Create public position object that tracks current position corners - cache.posClass = this._createPosClass( - (this.position = { my: posOptions.my, at: posOptions.at }).my - ); + // Set all of the defined options to their new values + $.each(option, function(notation, value) { + if(rendered && rrender.test(notation)) { + delete option[notation]; return; + } - // Create tooltip element - this.tooltip = elements.tooltip = tooltip = $('
', { - 'id': this._id, - 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, cache.posClass ].join(' '), - 'width': options.style.width || '', - 'height': options.style.height || '', - 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse, + // Set new obj value + var obj = convertNotation(options, notation.toLowerCase()), previous; + previous = obj[0][ obj[1] ]; + obj[0][ obj[1] ] = value && value.nodeType ? $(value) : value; - /* ARIA specific attributes */ - 'role': 'alert', - 'aria-live': 'polite', - 'aria-atomic': FALSE, - 'aria-describedby': this._id + '-content', - 'aria-hidden': TRUE + // Also check if we need to reposition + reposition = rmove.test(notation) || reposition; + + // Set the new params for the callback + option[notation] = [obj[0], obj[1], value, previous]; + }); + + // Re-sanitize options + sanitizeOptions(options); + + /* + * Execute any valid callbacks for the set options + * Also set positioning flag so we don't get loads of redundant repositioning calls. + */ + this.positioning = TRUE; + $.each(option, $.proxy(setCallback, this)); + this.positioning = FALSE; + + // Update position if needed + if(this.rendered && this.tooltip[0].offsetWidth > 0 && reposition) { + this.reposition( options.position.target === 'mouse' ? NULL : this.cache.event ); + } + + return this; +}; +;PROTOTYPE._update = function(content, element, reposition) { + var self = this, + cache = this.cache; + + // Make sure tooltip is rendered and content is defined. If not return + if(!this.rendered || !content) { return FALSE; } + + // Use function to parse content + if($.isFunction(content)) { + content = content.call(this.elements.target, cache.event, this) || ''; + } + + // Handle deferred content + if($.isFunction(content.then)) { + cache.waiting = TRUE; + return content.then(function(c) { + cache.waiting = FALSE; + return self._update(c, element); + }, NULL, function(e) { + return self._update(e, element); + }); + } + + // If content is null... return false + if(content === FALSE || (!content && content !== '')) { return FALSE; } + + // Append new content if its a DOM array and show it if hidden + if(content.jquery && content.length > 0) { + element.empty().append( + content.css({ display: 'block', visibility: 'visible' }) + ); + } + + // Content is a regular string, insert the new content + else { element.html(content); } + + // Wait for content to be loaded, and reposition + return this._waitForContent(element).then(function(images) { + if(self.rendered && self.tooltip[0].offsetWidth > 0) { + self.reposition(cache.event, !images.length); + } + }); +}; + +PROTOTYPE._waitForContent = function(element) { + var cache = this.cache; + + // Set flag + cache.waiting = TRUE; + + // If imagesLoaded is included, ensure images have loaded and return promise + return ( $.fn.imagesLoaded ? element.imagesLoaded() : $.Deferred().resolve([]) ) + .done(function() { cache.waiting = FALSE; }) + .promise(); +}; + +PROTOTYPE._updateContent = function(content, reposition) { + this._update(content, this.elements.content, reposition); +}; + +PROTOTYPE._updateTitle = function(content, reposition) { + if(this._update(content, this.elements.title, reposition) === FALSE) { + this._removeTitle(FALSE); + } +}; + +PROTOTYPE._createTitle = function() +{ + var elements = this.elements, + id = this._id+'-title'; + + // Destroy previous title element, if present + if(elements.titlebar) { this._removeTitle(); } + + // Create title bar and title elements + elements.titlebar = $('
', { + 'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ? createWidgetClass('header') : '') }) - .toggleClass(CLASS_DISABLED, this.disabled) - .attr(ATTR_ID, this.id) - .data(NAMESPACE, this) - .appendTo(posOptions.container) .append( - // Create content element - elements.content = $('
', { - 'class': NAMESPACE + '-content', - 'id': this._id + '-content', + elements.title = $('
', { + 'id': id, + 'class': NAMESPACE + '-title', 'aria-atomic': TRUE }) - ); + ) + .insertBefore(elements.content) - // Set rendered flag and prevent redundant reposition calls for now - this.rendered = -1; + // Button-specific events + .delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) { + $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down'); + }) + .delegate('.qtip-close', 'mouseover mouseout', function(event){ + $(this).toggleClass('ui-state-hover', event.type === 'mouseover'); + }); + + // Create button if enabled + if(this.options.content.button) { this._createButton(); } +}; + +PROTOTYPE._removeTitle = function(reposition) +{ + var elements = this.elements; + + if(elements.title) { + elements.titlebar.remove(); + elements.titlebar = elements.title = elements.button = NULL; + + // Reposition if enabled + if(reposition !== FALSE) { this.reposition(); } + } +}; +;PROTOTYPE._createPosClass = function(my) { + return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev(); +}; + +PROTOTYPE.reposition = function(event, effect) { + if(!this.rendered || this.positioning || this.destroyed) { return this; } + + // Set positioning flag this.positioning = TRUE; - // Create title... - if(title) { - this._createTitle(); + var cache = this.cache, + tooltip = this.tooltip, + posOptions = this.options.position, + target = posOptions.target, + my = posOptions.my, + at = posOptions.at, + viewport = posOptions.viewport, + container = posOptions.container, + adjust = posOptions.adjust, + method = adjust.method.split(' '), + tooltipWidth = tooltip.outerWidth(FALSE), + tooltipHeight = tooltip.outerHeight(FALSE), + targetWidth = 0, + targetHeight = 0, + type = tooltip.css('position'), + position = { left: 0, top: 0 }, + visible = tooltip[0].offsetWidth > 0, + isScroll = event && event.type === 'scroll', + win = $(window), + doc = container[0].ownerDocument, + mouse = this.mouse, + pluginCalculations, offset, adjusted, newClass; - // Update title only if its not a callback (called in toggle if so) - if(!$.isFunction(title)) { - deferreds.push( this._updateTitle(title, FALSE) ); + // Check if absolute position was passed + if($.isArray(target) && target.length === 2) { + // Force left top and set position + at = { x: LEFT, y: TOP }; + position = { left: target[0], top: target[1] }; + } + + // Check if mouse was the target + else if(target === 'mouse') { + // Force left top to allow flipping + at = { x: LEFT, y: TOP }; + + // Use the mouse origin that caused the show event, if distance hiding is enabled + if((!adjust.mouse || this.options.hide.distance) && cache.origin && cache.origin.pageX) { + event = cache.origin; + } + + // Use cached event for resize/scroll events + else if(!event || (event && (event.type === 'resize' || event.type === 'scroll'))) { + event = cache.event; + } + + // Otherwise, use the cached mouse coordinates if available + else if(mouse && mouse.pageX) { + event = mouse; + } + + // Calculate body and container offset and take them into account below + if(type !== 'static') { position = container.offset(); } + if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) { + offset = $(document.body).offset(); + } + + // Use event coordinates for position + position = { + left: event.pageX - position.left + (offset && offset.left || 0), + top: event.pageY - position.top + (offset && offset.top || 0) + }; + + // Scroll events are a pain, some browsers + if(adjust.mouse && isScroll && mouse) { + position.left -= (mouse.scrollX || 0) - win.scrollLeft(); + position.top -= (mouse.scrollY || 0) - win.scrollTop(); } } - // Create button - if(button) { this._createButton(); } + // Target wasn't mouse or absolute... + else { + // Check if event targetting is being used + if(target === 'event') { + if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') { + cache.target = $(event.target); + } + else if(!event.target) { + cache.target = this.elements.target; + } + } + else if(target !== 'event'){ + cache.target = $(target.jquery ? target : this.elements.target); + } + target = cache.target; - // Set proper rendered flag and update content if not a callback function (called in toggle) - if(!$.isFunction(text)) { - deferreds.push( this._updateContent(text, FALSE) ); + // Parse the target into a jQuery object and make sure there's an element present + target = $(target).eq(0); + if(target.length === 0) { return this; } + + // Check if window or document is the target + else if(target[0] === document || target[0] === window) { + targetWidth = BROWSER.iOS ? window.innerWidth : target.width(); + targetHeight = BROWSER.iOS ? window.innerHeight : target.height(); + + if(target[0] === window) { + position = { + top: (viewport || target).scrollTop(), + left: (viewport || target).scrollLeft() + }; + } + } + + // Check if the target is an element + else if(PLUGINS.imagemap && target.is('area')) { + pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE); + } + + // Check if the target is an SVG element + else if(PLUGINS.svg && target && target[0].ownerSVGElement) { + pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE); + } + + // Otherwise use regular jQuery methods + else { + targetWidth = target.outerWidth(FALSE); + targetHeight = target.outerHeight(FALSE); + position = target.offset(); + } + + // Parse returned plugin values into proper variables + if(pluginCalculations) { + targetWidth = pluginCalculations.width; + targetHeight = pluginCalculations.height; + offset = pluginCalculations.offset; + position = pluginCalculations.position; + } + + // Adjust position to take into account offset parents + position = this.reposition.offset(target, position, container); + + // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2) + if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) || + (BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) || + (!BROWSER.iOS && type === 'fixed') + ){ + position.left -= win.scrollLeft(); + position.top -= win.scrollTop(); + } + + // Adjust position relative to target + if(!pluginCalculations || (pluginCalculations && pluginCalculations.adjustable !== FALSE)) { + position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0; + position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0; + } } - this.rendered = TRUE; - // Setup widget classes - this._setWidget(); + // Adjust position relative to tooltip + position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0); + position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0); - // Initialize 'render' plugins - $.each(PLUGINS, function(name) { - var instance; - if(this.initialize === 'render' && (instance = this(self))) { - self.plugins[name] = instance; - } - }); + // Use viewport adjustment plugin if enabled + if(PLUGINS.viewport) { + adjusted = position.adjusted = PLUGINS.viewport( + this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight + ); - // Unassign initial events and assign proper events - this._unassignEvents(); - this._assignEvents(); + // Apply offsets supplied by positioning plugin (if used) + if(offset && adjusted.left) { position.left += offset.left; } + if(offset && adjusted.top) { position.top += offset.top; } - // When deferreds have completed - this._when(deferreds).then(function() { - // tooltiprender event - self._trigger('render'); + // Apply any new 'my' position + if(adjusted.my) { this.position.my = adjusted.my; } + } - // Reset flags - self.positioning = FALSE; + // Viewport adjustment is disabled, set values to zero + else { position.adjusted = { left: 0, top: 0 }; } - // Show tooltip if not hidden during wait period - if(!self.hiddenDuringWait && (options.show.ready || show)) { - self.toggle(TRUE, cache.event, FALSE); - } - self.hiddenDuringWait = FALSE; - }); + // Set tooltip position class if it's changed + if(cache.posClass !== (newClass = this._createPosClass(this.position.my))) { + tooltip.removeClass(cache.posClass).addClass( (cache.posClass = newClass) ); + } - // Expose API - QTIP.api[this.id] = this; + // tooltipmove event + if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; } + delete position.adjusted; + + // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly + if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) { + tooltip.css(position); + } + + // Use custom function if provided + else if($.isFunction(posOptions.effect)) { + posOptions.effect.call(tooltip, this, $.extend({}, position)); + tooltip.queue(function(next) { + // Reset attributes to avoid cross-browser rendering bugs + $(this).css({ opacity: '', height: '' }); + if(BROWSER.ie) { this.style.removeAttribute('filter'); } + + next(); + }); + } + + // Set positioning flag + this.positioning = FALSE; return this; }; -PROTOTYPE.destroy = function(immediate) { - // Set flag the signify destroy is taking place to plugins - // and ensure it only gets destroyed once! - if(this.destroyed) { return this.target; } +// Custom (more correct for qTip!) offset calculator +PROTOTYPE.reposition.offset = function(elem, pos, container) { + if(!container[0]) { return pos; } - function process() { - if(this.destroyed) { return; } - this.destroyed = TRUE; + var ownerDocument = $(elem[0].ownerDocument), + quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat', + parent = container[0], + scrolled, position, parentOffset, overflow; - var target = this.target, - title = target.attr(oldtitle), - timer; + function scroll(e, i) { + pos.left += i * e.scrollLeft(); + pos.top += i * e.scrollTop(); + } - // Destroy tooltip if rendered - if(this.rendered) { - this.tooltip.stop(1,0).find('*').remove().end().remove(); + // Compensate for non-static containers offset + do { + if((position = $.css(parent, 'position')) !== 'static') { + if(position === 'fixed') { + parentOffset = parent.getBoundingClientRect(); + scroll(ownerDocument, -1); + } + else { + parentOffset = $(parent).position(); + parentOffset.left += (parseFloat($.css(parent, 'borderLeftWidth')) || 0); + parentOffset.top += (parseFloat($.css(parent, 'borderTopWidth')) || 0); + } + + pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0); + pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0); + + // If this is the first parent element with an overflow of "scroll" or "auto", store it + if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); } + } + } + while((parent = parent.offsetParent)); + + // Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode) + if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) { + scroll(scrolled, 1); + } + + return pos; +}; + +// Corner class +var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) { + corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase(); + this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase(); + this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase(); + this.forceY = !!forceY; + + var f = corner.charAt(0); + this.precedance = (f === 't' || f === 'b' ? Y : X); +}).prototype; + +C.invert = function(z, center) { + this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z]; +}; + +C.string = function(join) { + var x = this.x, y = this.y; + + var result = x !== y ? + (x === 'center' || y !== 'center' && (this.precedance === Y || this.forceY) ? + [y,x] : [x,y] + ) : + [x]; + + return join !== false ? result.join(' ') : result; +}; + +C.abbrev = function() { + var result = this.string(false); + return result[0].charAt(0) + (result[1] && result[1].charAt(0) || ''); +}; + +C.clone = function() { + return new CORNER( this.string(), this.forceY ); +}; + +; +PROTOTYPE.toggle = function(state, event) { + var cache = this.cache, + options = this.options, + tooltip = this.tooltip; + + // Try to prevent flickering when tooltip overlaps show element + if(event) { + if((/over|enter/).test(event.type) && cache.event && (/out|leave/).test(cache.event.type) && + options.show.target.add(event.target).length === options.show.target.length && + tooltip.has(event.relatedTarget).length) { + return this; } - // Destroy all plugins - $.each(this.plugins, function(name) { - this.destroy && this.destroy(); + // Cache event + cache.event = $.event.fix(event); + } + + // If we're currently waiting and we've just hidden... stop it + this.waiting && !state && (this.hiddenDuringWait = TRUE); + + // Render the tooltip if showing and it isn't already + if(!this.rendered) { return state ? this.render(1) : this; } + else if(this.destroyed || this.disabled) { return this; } + + var type = state ? 'show' : 'hide', + opts = this.options[type], + otherOpts = this.options[ !state ? 'show' : 'hide' ], + posOptions = this.options.position, + contentOptions = this.options.content, + width = this.tooltip.css('width'), + visible = this.tooltip.is(':visible'), + animate = state || opts.target.length === 1, + sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target, + identicalState, allow, showEvent, delay, after; + + // Detect state if valid one isn't provided + if((typeof state).search('boolean|number')) { state = !visible; } + + // Check if the tooltip is in an identical state to the new would-be state + identicalState = !tooltip.is(':animated') && visible === state && sameTarget; + + // Fire tooltip(show/hide) event and check if destroyed + allow = !identicalState ? !!this._trigger(type, [90]) : NULL; + + // Check to make sure the tooltip wasn't destroyed in the callback + if(this.destroyed) { return this; } + + // If the user didn't stop the method prematurely and we're showing the tooltip, focus it + if(allow !== FALSE && state) { this.focus(event); } + + // If the state hasn't changed or the user stopped it, return early + if(!allow || identicalState) { return this; } + + // Set ARIA hidden attribute + $.attr(tooltip[0], 'aria-hidden', !!!state); + + // Execute state specific properties + if(state) { + // Store show origin coordinates + this.mouse && (cache.origin = $.event.fix(this.mouse)); + + // Update tooltip content & title if it's a dynamic function + if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); } + if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); } + + // Cache mousemove events for positioning purposes (if not already tracking) + if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) { + $(document).bind('mousemove.'+NAMESPACE, this._storeMouse); + trackingBound = TRUE; + } + + // Update the tooltip position (set width first to prevent viewport/max-width issues) + if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); } + this.reposition(event, arguments[2]); + if(!width) { tooltip.css('width', ''); } + + // Hide other tooltips if tooltip is solo + if(!!opts.solo) { + (typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo)) + .not(tooltip).not(opts.target).qtip('hide', $.Event('tooltipsolo')); + } + } + else { + // Clear show timer if we're hiding + clearTimeout(this.timers.show); + + // Remove cached origin on hide + delete cache.origin; + + // Remove mouse tracking event if not needed (all tracking qTips are hidden) + if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) { + $(document).unbind('mousemove.'+NAMESPACE); + trackingBound = FALSE; + } + + // Blur the tooltip + this.blur(event); + } + + // Define post-animation, state specific properties + after = $.proxy(function() { + if(state) { + // Prevent antialias from disappearing in IE by removing filter + if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); } + + // Remove overflow setting to prevent tip bugs + tooltip.css('overflow', ''); + + // Autofocus elements if enabled + if('string' === typeof opts.autofocus) { + $(this.options.show.autofocus, tooltip).focus(); + } + + // If set, hide tooltip when inactive for delay period + this.options.show.target.trigger('qtip-'+this.id+'-inactive'); + } + else { + // Reset CSS states + tooltip.css({ + display: '', + visibility: '', + opacity: '', + left: '', + top: '' + }); + } + + // tooltipvisible/tooltiphidden events + this._trigger(state ? 'visible' : 'hidden'); + }, this); + + // If no effect type is supplied, use a simple toggle + if(opts.effect === FALSE || animate === FALSE) { + tooltip[ type ](); + after(); + } + + // Use custom function if provided + else if($.isFunction(opts.effect)) { + tooltip.stop(1, 1); + opts.effect.call(tooltip, this); + tooltip.queue('fx', function(n) { + after(); n(); + }); + } + + // Use basic fade function by default + else { tooltip.fadeTo(90, state ? 1 : 0, after); } + + // If inactive hide method is set, active it + if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); } + + return this; +}; + +PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); }; + +PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); }; +;PROTOTYPE.focus = function(event) { + if(!this.rendered || this.destroyed) { return this; } + + var qtips = $(SELECTOR), + tooltip = this.tooltip, + curIndex = parseInt(tooltip[0].style.zIndex, 10), + newIndex = QTIP.zindex + qtips.length, + focusedElem; + + // Only update the z-index if it has changed and tooltip is not already focused + if(!tooltip.hasClass(CLASS_FOCUS)) { + // tooltipfocus event + if(this._trigger('focus', [newIndex], event)) { + // Only update z-index's if they've changed + if(curIndex !== newIndex) { + // Reduce our z-index's and keep them properly ordered + qtips.each(function() { + if(this.style.zIndex > curIndex) { + this.style.zIndex = this.style.zIndex - 1; + } + }); + + // Fire blur event for focused tooltip + qtips.filter('.' + CLASS_FOCUS).qtip('blur', event); + } + + // Set the new z-index + tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; + } + } + + return this; +}; + +PROTOTYPE.blur = function(event) { + if(!this.rendered || this.destroyed) { return this; } + + // Set focused status to FALSE + this.tooltip.removeClass(CLASS_FOCUS); + + // tooltipblur event + this._trigger('blur', [ this.tooltip.css('zIndex') ], event); + + return this; +}; +;PROTOTYPE.disable = function(state) { + if(this.destroyed) { return this; } + + // If 'toggle' is passed, toggle the current state + if(state === 'toggle') { + state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled); + } + + // Disable if no state passed + else if('boolean' !== typeof state) { + state = TRUE; + } + + if(this.rendered) { + this.tooltip.toggleClass(CLASS_DISABLED, state) + .attr('aria-disabled', state); + } + + this.disabled = !!state; + + return this; +}; + +PROTOTYPE.enable = function() { return this.disable(FALSE); }; +;PROTOTYPE._createButton = function() +{ + var self = this, + elements = this.elements, + tooltip = elements.tooltip, + button = this.options.content.button, + isString = typeof button === 'string', + close = isString ? button : 'Close tooltip'; + + if(elements.button) { elements.button.remove(); } + + // Use custom button if one was supplied by user, else use default + if(button.jquery) { + elements.button = button; + } + else { + elements.button = $('', { + 'class': 'qtip-close ' + (this.options.style.widget ? '' : NAMESPACE+'-icon'), + 'title': close, + 'aria-label': close + }) + .prepend( + $('', { + 'class': 'ui-icon ui-icon-close', + 'html': '×' + }) + ); + } + + // Create button and setup attributes + elements.button.appendTo(elements.titlebar || tooltip) + .attr('role', 'button') + .click(function(event) { + if(!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); } + return FALSE; + }); +}; + +PROTOTYPE._updateButton = function(button) +{ + // Make sure tooltip is rendered and if not, return + if(!this.rendered) { return FALSE; } + + var elem = this.elements.button; + if(button) { this._createButton(); } + else { elem.remove(); } +}; +;// Widget class creator +function createWidgetClass(cls) { + return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' '); +} + +// Widget class setter method +PROTOTYPE._setWidget = function() +{ + var on = this.options.style.widget, + elements = this.elements, + tooltip = elements.tooltip, + disabled = tooltip.hasClass(CLASS_DISABLED); + + tooltip.removeClass(CLASS_DISABLED); + CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled'; + tooltip.toggleClass(CLASS_DISABLED, disabled); + + tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on); + + if(elements.content) { + elements.content.toggleClass( createWidgetClass('content'), on); + } + if(elements.titlebar) { + elements.titlebar.toggleClass( createWidgetClass('header'), on); + } + if(elements.button) { + elements.button.toggleClass(NAMESPACE+'-icon', !on); + } +}; +;function delay(callback, duration) { + // If tooltip has displayed, start hide timer + if(duration > 0) { + return setTimeout( + $.proxy(callback, this), duration + ); + } + else{ callback.call(this); } +} + +function showMethod(event) { + if(this.tooltip.hasClass(CLASS_DISABLED)) { return; } + + // Clear hide timers + clearTimeout(this.timers.show); + clearTimeout(this.timers.hide); + + // Start show timer + this.timers.show = delay.call(this, + function() { this.toggle(TRUE, event); }, + this.options.show.delay + ); +} + +function hideMethod(event) { + if(this.tooltip.hasClass(CLASS_DISABLED) || this.destroyed) { return; } + + // Check if new target was actually the tooltip element + var relatedTarget = $(event.relatedTarget), + ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.tooltip[0], + ontoTarget = relatedTarget[0] === this.options.show.target[0]; + + // Clear timers and stop animation queue + clearTimeout(this.timers.show); + clearTimeout(this.timers.hide); + + // Prevent hiding if tooltip is fixed and event target is the tooltip. + // Or if mouse positioning is enabled and cursor momentarily overlaps + if(this !== relatedTarget[0] && + (this.options.position.target === 'mouse' && ontoTooltip) || + (this.options.hide.fixed && ( + (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)) + )) + { + try { + event.preventDefault(); + event.stopImmediatePropagation(); + } catch(e) {} + + return; + } + + // If tooltip has displayed, start hide timer + this.timers.hide = delay.call(this, + function() { this.toggle(FALSE, event); }, + this.options.hide.delay, + this + ); +} + +function inactiveMethod(event) { + if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return; } + + // Clear timer + clearTimeout(this.timers.inactive); + + this.timers.inactive = delay.call(this, + function(){ this.hide(event); }, + this.options.hide.inactive + ); +} + +function repositionMethod(event) { + if(this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } +} + +// Store mouse coordinates +PROTOTYPE._storeMouse = function(event) { + (this.mouse = $.event.fix(event)).type = 'mousemove'; + return this; +}; + +// Bind events +PROTOTYPE._bind = function(targets, events, method, suffix, context) { + if(!targets || !method || !events.length) { return; } + var ns = '.' + this._id + (suffix ? '-'+suffix : ''); + $(targets).bind( + (events.split ? events : events.join(ns + ' ')) + ns, + $.proxy(method, context || this) + ); + return this; +}; +PROTOTYPE._unbind = function(targets, suffix) { + targets && $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : '')); + return this; +}; + +// Global delegation helper +function delegate(selector, events, method) { + $(document.body).delegate(selector, + (events.split ? events : events.join('.'+NAMESPACE + ' ')) + '.'+NAMESPACE, + function() { + var api = QTIP.api[ $.attr(this, ATTR_ID) ]; + api && !api.disabled && method.apply(api, arguments); + } + ); +} +// Event trigger +PROTOTYPE._trigger = function(type, args, event) { + var callback = $.Event('tooltip'+type); + callback.originalEvent = (event && $.extend({}, event)) || this.cache.event || NULL; + + this.triggering = type; + this.tooltip.trigger(callback, [this].concat(args || [])); + this.triggering = FALSE; + + return !callback.isDefaultPrevented(); +}; + +PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTargets, hideTargets, showMethod, hideMethod) { + // Get tasrgets that lye within both + var similarTargets = showTargets.filter( hideTargets ).add( hideTargets.filter(showTargets) ), + toggleEvents = []; + + // If hide and show targets are the same... + if(similarTargets.length) { + + // Filter identical show/hide events + $.each(hideEvents, function(i, type) { + var showIndex = $.inArray(type, showEvents); + + // Both events are identical, remove from both hide and show events + // and append to toggleEvents + showIndex > -1 && toggleEvents.push( showEvents.splice( showIndex, 1 )[0] ); }); - // Clear timers - for(timer in this.timers) { - clearTimeout(this.timers[timer]); + // Toggle events are special case of identical show/hide events, which happen in sequence + if(toggleEvents.length) { + // Bind toggle events to the similar targets + this._bind(similarTargets, toggleEvents, function(event) { + var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false; + (state ? hideMethod : showMethod).call(this, event); + }); + + // Remove the similar targets from the regular show/hide bindings + showTargets = showTargets.not(similarTargets); + hideTargets = hideTargets.not(similarTargets); } - - // Remove api object and ARIA attributes - target.removeData(NAMESPACE) - .removeAttr(ATTR_ID) - .removeAttr(ATTR_HAS) - .removeAttr('aria-describedby'); - - // Reset old title attribute if removed - if(this.options.suppress && title) { - target.attr('title', title).removeAttr(oldtitle); - } - - // Remove qTip events associated with this API - this._unassignEvents(); - - // Remove ID from used id objects, and delete object references - // for better garbage collection and leak protection - this.options = this.elements = this.cache = this.timers = - this.plugins = this.mouse = NULL; - - // Delete epoxsed API object - delete QTIP.api[this.id]; } - // If an immediate destory is needed - if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) { - this.tooltip.one('tooltiphidden', $.proxy(process, this)); - !this.triggering && this.hide(); - } - - // If we're not in the process of hiding... process - else { process.call(this); } - - return this.target; + // Apply show/hide/toggle events + this._bind(showTargets, showEvents, showMethod); + this._bind(hideTargets, hideEvents, hideMethod); }; -;function invalidOpt(a) { - return a === NULL || $.type(a) !== 'object'; -} - -function invalidContent(c) { - return !( $.isFunction(c) || (c && c.attr) || c.length || ($.type(c) === 'object' && (c.jquery || c.then) )); -} - -// Option object sanitizer -function sanitizeOptions(opts) { - var content, text, ajax, once; - - if(invalidOpt(opts)) { return FALSE; } - - if(invalidOpt(opts.metadata)) { - opts.metadata = { type: opts.metadata }; - } - - if('content' in opts) { - content = opts.content; - - if(invalidOpt(content) || content.jquery || content.done) { - content = opts.content = { - text: (text = invalidContent(content) ? FALSE : content) - }; - } - else { text = content.text; } - - // DEPRECATED - Old content.ajax plugin functionality - // Converts it into the proper Deferred syntax - if('ajax' in content) { - ajax = content.ajax; - once = ajax && ajax.once !== FALSE; - delete content.ajax; - - content.text = function(event, api) { - var loading = text || $(this).attr(api.options.content.attr) || 'Loading...', - - deferred = $.ajax( - $.extend({}, ajax, { context: api }) - ) - .then(ajax.success, NULL, ajax.error) - .then(function(content) { - if(content && once) { api.set('content.text', content); } - return content; - }, - function(xhr, status, error) { - if(api.destroyed || xhr.status === 0) { return; } - api.set('content.text', status + ': ' + error); - }); - - return !once ? (api.set('content.text', loading), deferred) : loading; - }; - } - - if('title' in content) { - if($.isPlainObject(content.title)) { - content.button = content.title.button; - content.title = content.title.text; - } - - if(invalidContent(content.title || FALSE)) { - content.title = FALSE; - } - } - } - - if('position' in opts && invalidOpt(opts.position)) { - opts.position = { my: opts.position, at: opts.position }; - } - - if('show' in opts && invalidOpt(opts.show)) { - opts.show = opts.show.jquery ? { target: opts.show } : - opts.show === TRUE ? { ready: TRUE } : { event: opts.show }; - } - - if('hide' in opts && invalidOpt(opts.hide)) { - opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide }; - } - - if('style' in opts && invalidOpt(opts.style)) { - opts.style = { classes: opts.style }; - } - - // Sanitize plugin options - $.each(PLUGINS, function() { - this.sanitize && this.sanitize(opts); - }); - - return opts; -} - -// Setup builtin .set() option checks -CHECKS = PROTOTYPE.checks = { - builtin: { - // Core checks - '^id$': function(obj, o, v, prev) { - var id = v === TRUE ? QTIP.nextid : v, - new_id = NAMESPACE + '-' + id; - - if(id !== FALSE && id.length > 0 && !$('#'+new_id).length) { - this._id = new_id; - - if(this.rendered) { - this.tooltip[0].id = this._id; - this.elements.content[0].id = this._id + '-content'; - this.elements.title[0].id = this._id + '-title'; - } - } - else { obj[o] = prev; } - }, - '^prerender': function(obj, o, v) { - v && !this.rendered && this.render(this.options.show.ready); - }, - - // Content checks - '^content.text$': function(obj, o, v) { - this._updateContent(v); - }, - '^content.attr$': function(obj, o, v, prev) { - if(this.options.content.text === this.target.attr(prev)) { - this._updateContent( this.target.attr(v) ); - } - }, - '^content.title$': function(obj, o, v) { - // Remove title if content is null - if(!v) { return this._removeTitle(); } - - // If title isn't already created, create it now and update - v && !this.elements.title && this._createTitle(); - this._updateTitle(v); - }, - '^content.button$': function(obj, o, v) { - this._updateButton(v); - }, - '^content.title.(text|button)$': function(obj, o, v) { - this.set('content.'+o, v); // Backwards title.text/button compat - }, - - // Position checks - '^position.(my|at)$': function(obj, o, v){ - 'string' === typeof v && (this.position[o] = obj[o] = new CORNER(v, o === 'at')); - }, - '^position.container$': function(obj, o, v){ - this.rendered && this.tooltip.appendTo(v); - }, - - // Show checks - '^show.ready$': function(obj, o, v) { - v && (!this.rendered && this.render(TRUE) || this.toggle(TRUE)); - }, - - // Style checks - '^style.classes$': function(obj, o, v, p) { - this.rendered && this.tooltip.removeClass(p).addClass(v); - }, - '^style.(width|height)': function(obj, o, v) { - this.rendered && this.tooltip.css(o, v); - }, - '^style.widget|content.title': function() { - this.rendered && this._setWidget(); - }, - '^style.def': function(obj, o, v) { - this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v); - }, - - // Events check - '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) { - this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v); - }, - - // Properties which require event reassignment - '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() { - if(!this.rendered) { return; } - - // Set tracking flag - var posOptions = this.options.position; - this.tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse); - - // Reassign events - this._unassignEvents(); - this._assignEvents(); - } - } -}; - -// Dot notation converter -function convertNotation(options, notation) { - var i = 0, obj, option = options, - - // Split notation into array - levels = notation.split('.'); - - // Loop through - while( option = option[ levels[i++] ] ) { - if(i < levels.length) { obj = option; } - } - - return [obj || options, levels.pop()]; -} - -PROTOTYPE.get = function(notation) { - if(this.destroyed) { return this; } - - var o = convertNotation(this.options, notation.toLowerCase()), - result = o[0][ o[1] ]; - - return result.precedance ? result.string() : result; -}; - -function setCallback(notation, args) { - var category, rule, match; - - for(category in this.checks) { - for(rule in this.checks[category]) { - if(match = (new RegExp(rule, 'i')).exec(notation)) { - args.push(match); - - if(category === 'builtin' || this.plugins[category]) { - this.checks[category][rule].apply( - this.plugins[category] || this, args - ); - } - } - } - } -} - -var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i, - rrender = /^prerender|show\.ready/i; - -PROTOTYPE.set = function(option, value) { - if(this.destroyed) { return this; } - - var rendered = this.rendered, - reposition = FALSE, - options = this.options, - checks = this.checks, - name; - - // Convert singular option/value pair into object form - if('string' === typeof option) { - name = option; option = {}; option[name] = value; - } - else { option = $.extend({}, option); } - - // Set all of the defined options to their new values - $.each(option, function(notation, value) { - if(rendered && rrender.test(notation)) { - delete option[notation]; return; - } - - // Set new obj value - var obj = convertNotation(options, notation.toLowerCase()), previous; - previous = obj[0][ obj[1] ]; - obj[0][ obj[1] ] = value && value.nodeType ? $(value) : value; - - // Also check if we need to reposition - reposition = rmove.test(notation) || reposition; - - // Set the new params for the callback - option[notation] = [obj[0], obj[1], value, previous]; - }); - - // Re-sanitize options - sanitizeOptions(options); - - /* - * Execute any valid callbacks for the set options - * Also set positioning flag so we don't get loads of redundant repositioning calls. - */ - this.positioning = TRUE; - $.each(option, $.proxy(setCallback, this)); - this.positioning = FALSE; - - // Update position if needed - if(this.rendered && this.tooltip[0].offsetWidth > 0 && reposition) { - this.reposition( options.position.target === 'mouse' ? NULL : this.cache.event ); - } - - return this; -}; -;PROTOTYPE._update = function(content, element, reposition) { - var self = this, - cache = this.cache; - - // Make sure tooltip is rendered and content is defined. If not return - if(!this.rendered || !content) { return FALSE; } - - // Use function to parse content - if($.isFunction(content)) { - content = content.call(this.elements.target, cache.event, this) || ''; - } - - // Handle deferred content - if($.isFunction(content.then)) { - cache.waiting = TRUE; - return content.then(function(c) { - cache.waiting = FALSE; - return self._update(c, element); - }, NULL, function(e) { - return self._update(e, element); - }); - } - - // If content is null... return false - if(content === FALSE || (!content && content !== '')) { return FALSE; } - - // Append new content if its a DOM array and show it if hidden - if(content.jquery && content.length > 0) { - element.empty().append( - content.css({ display: 'block', visibility: 'visible' }) - ); - } - - // Content is a regular string, insert the new content - else { element.html(content); } - - // Wait for content to be loaded, and reposition - return this._waitForContent(element).then(function(images) { - if(self.rendered && self.tooltip[0].offsetWidth > 0) { - self.reposition(cache.event, !images.length); - } - }); -}; - -PROTOTYPE._waitForContent = function(element) { - var cache = this.cache; - - // Set flag - cache.waiting = TRUE; - - // If imagesLoaded is included, ensure images have loaded and return promise - return ( $.fn.imagesLoaded ? element.imagesLoaded() : $.Deferred().resolve([]) ) - .done(function() { cache.waiting = FALSE; }) - .promise(); -}; - -PROTOTYPE._updateContent = function(content, reposition) { - this._update(content, this.elements.content, reposition); -}; - -PROTOTYPE._updateTitle = function(content, reposition) { - if(this._update(content, this.elements.title, reposition) === FALSE) { - this._removeTitle(FALSE); - } -}; - -PROTOTYPE._createTitle = function() -{ - var elements = this.elements, - id = this._id+'-title'; - - // Destroy previous title element, if present - if(elements.titlebar) { this._removeTitle(); } - - // Create title bar and title elements - elements.titlebar = $('
', { - 'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ? createWidgetClass('header') : '') - }) - .append( - elements.title = $('
', { - 'id': id, - 'class': NAMESPACE + '-title', - 'aria-atomic': TRUE - }) - ) - .insertBefore(elements.content) - - // Button-specific events - .delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) { - $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down'); - }) - .delegate('.qtip-close', 'mouseover mouseout', function(event){ - $(this).toggleClass('ui-state-hover', event.type === 'mouseover'); - }); - - // Create button if enabled - if(this.options.content.button) { this._createButton(); } -}; - -PROTOTYPE._removeTitle = function(reposition) -{ - var elements = this.elements; - - if(elements.title) { - elements.titlebar.remove(); - elements.titlebar = elements.title = elements.button = NULL; - - // Reposition if enabled - if(reposition !== FALSE) { this.reposition(); } - } -}; -;PROTOTYPE._createPosClass = function(my) { - return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev(); -}; - -PROTOTYPE.reposition = function(event, effect) { - if(!this.rendered || this.positioning || this.destroyed) { return this; } - - // Set positioning flag - this.positioning = TRUE; - - var cache = this.cache, - tooltip = this.tooltip, - posOptions = this.options.position, - target = posOptions.target, - my = posOptions.my, - at = posOptions.at, - viewport = posOptions.viewport, - container = posOptions.container, - adjust = posOptions.adjust, - method = adjust.method.split(' '), - tooltipWidth = tooltip.outerWidth(FALSE), - tooltipHeight = tooltip.outerHeight(FALSE), - targetWidth = 0, - targetHeight = 0, - type = tooltip.css('position'), - position = { left: 0, top: 0 }, - visible = tooltip[0].offsetWidth > 0, - isScroll = event && event.type === 'scroll', - win = $(window), - doc = container[0].ownerDocument, - mouse = this.mouse, - pluginCalculations, offset, adjusted, newClass; - - // Check if absolute position was passed - if($.isArray(target) && target.length === 2) { - // Force left top and set position - at = { x: LEFT, y: TOP }; - position = { left: target[0], top: target[1] }; - } - - // Check if mouse was the target - else if(target === 'mouse') { - // Force left top to allow flipping - at = { x: LEFT, y: TOP }; - - // Use the mouse origin that caused the show event, if distance hiding is enabled - if((!adjust.mouse || this.options.hide.distance) && cache.origin && cache.origin.pageX) { - event = cache.origin; - } - - // Use cached event for resize/scroll events - else if(!event || (event && (event.type === 'resize' || event.type === 'scroll'))) { - event = cache.event; - } - - // Otherwise, use the cached mouse coordinates if available - else if(mouse && mouse.pageX) { - event = mouse; - } - - // Calculate body and container offset and take them into account below - if(type !== 'static') { position = container.offset(); } - if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) { - offset = $(document.body).offset(); - } - - // Use event coordinates for position - position = { - left: event.pageX - position.left + (offset && offset.left || 0), - top: event.pageY - position.top + (offset && offset.top || 0) - }; - - // Scroll events are a pain, some browsers - if(adjust.mouse && isScroll && mouse) { - position.left -= (mouse.scrollX || 0) - win.scrollLeft(); - position.top -= (mouse.scrollY || 0) - win.scrollTop(); - } - } - - // Target wasn't mouse or absolute... - else { - // Check if event targetting is being used - if(target === 'event') { - if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') { - cache.target = $(event.target); - } - else if(!event.target) { - cache.target = this.elements.target; - } - } - else if(target !== 'event'){ - cache.target = $(target.jquery ? target : this.elements.target); - } - target = cache.target; - - // Parse the target into a jQuery object and make sure there's an element present - target = $(target).eq(0); - if(target.length === 0) { return this; } - - // Check if window or document is the target - else if(target[0] === document || target[0] === window) { - targetWidth = BROWSER.iOS ? window.innerWidth : target.width(); - targetHeight = BROWSER.iOS ? window.innerHeight : target.height(); - - if(target[0] === window) { - position = { - top: (viewport || target).scrollTop(), - left: (viewport || target).scrollLeft() - }; - } - } - - // Check if the target is an element - else if(PLUGINS.imagemap && target.is('area')) { - pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE); - } - - // Check if the target is an SVG element - else if(PLUGINS.svg && target && target[0].ownerSVGElement) { - pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE); - } - - // Otherwise use regular jQuery methods - else { - targetWidth = target.outerWidth(FALSE); - targetHeight = target.outerHeight(FALSE); - position = target.offset(); - } - - // Parse returned plugin values into proper variables - if(pluginCalculations) { - targetWidth = pluginCalculations.width; - targetHeight = pluginCalculations.height; - offset = pluginCalculations.offset; - position = pluginCalculations.position; - } - - // Adjust position to take into account offset parents - position = this.reposition.offset(target, position, container); - - // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2) - if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) || - (BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) || - (!BROWSER.iOS && type === 'fixed') - ){ - position.left -= win.scrollLeft(); - position.top -= win.scrollTop(); - } - - // Adjust position relative to target - if(!pluginCalculations || (pluginCalculations && pluginCalculations.adjustable !== FALSE)) { - position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0; - position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0; - } - } - - // Adjust position relative to tooltip - position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0); - position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0); - - // Use viewport adjustment plugin if enabled - if(PLUGINS.viewport) { - adjusted = position.adjusted = PLUGINS.viewport( - this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight - ); - - // Apply offsets supplied by positioning plugin (if used) - if(offset && adjusted.left) { position.left += offset.left; } - if(offset && adjusted.top) { position.top += offset.top; } - - // Apply any new 'my' position - if(adjusted.my) { this.position.my = adjusted.my; } - } - - // Viewport adjustment is disabled, set values to zero - else { position.adjusted = { left: 0, top: 0 }; } - - // Set tooltip position class if it's changed - if(cache.posClass !== (newClass = this._createPosClass(this.position.my))) { - tooltip.removeClass(cache.posClass).addClass( (cache.posClass = newClass) ); - } - - // tooltipmove event - if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; } - delete position.adjusted; - - // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly - if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) { - tooltip.css(position); - } - - // Use custom function if provided - else if($.isFunction(posOptions.effect)) { - posOptions.effect.call(tooltip, this, $.extend({}, position)); - tooltip.queue(function(next) { - // Reset attributes to avoid cross-browser rendering bugs - $(this).css({ opacity: '', height: '' }); - if(BROWSER.ie) { this.style.removeAttribute('filter'); } - - next(); - }); - } - - // Set positioning flag - this.positioning = FALSE; - - return this; -}; - -// Custom (more correct for qTip!) offset calculator -PROTOTYPE.reposition.offset = function(elem, pos, container) { - if(!container[0]) { return pos; } - - var ownerDocument = $(elem[0].ownerDocument), - quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat', - parent = container[0], - scrolled, position, parentOffset, overflow; - - function scroll(e, i) { - pos.left += i * e.scrollLeft(); - pos.top += i * e.scrollTop(); - } - - // Compensate for non-static containers offset - do { - if((position = $.css(parent, 'position')) !== 'static') { - if(position === 'fixed') { - parentOffset = parent.getBoundingClientRect(); - scroll(ownerDocument, -1); - } - else { - parentOffset = $(parent).position(); - parentOffset.left += (parseFloat($.css(parent, 'borderLeftWidth')) || 0); - parentOffset.top += (parseFloat($.css(parent, 'borderTopWidth')) || 0); - } - - pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0); - pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0); - - // If this is the first parent element with an overflow of "scroll" or "auto", store it - if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); } - } - } - while((parent = parent.offsetParent)); - - // Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode) - if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) { - scroll(scrolled, 1); - } - - return pos; -}; - -// Corner class -var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) { - corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase(); - this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase(); - this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase(); - this.forceY = !!forceY; - - var f = corner.charAt(0); - this.precedance = (f === 't' || f === 'b' ? Y : X); -}).prototype; - -C.invert = function(z, center) { - this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z]; -}; - -C.string = function(join) { - var x = this.x, y = this.y; - - var result = x !== y ? - (x === 'center' || y !== 'center' && (this.precedance === Y || this.forceY) ? - [y,x] : [x,y] - ) : - [x]; - - return join !== false ? result.join(' ') : result; -}; - -C.abbrev = function() { - var result = this.string(false); - return result[0].charAt(0) + (result[1] && result[1].charAt(0) || ''); -}; - -C.clone = function() { - return new CORNER( this.string(), this.forceY ); -}; - -; -PROTOTYPE.toggle = function(state, event) { - var cache = this.cache, - options = this.options, - tooltip = this.tooltip; - - // Try to prevent flickering when tooltip overlaps show element - if(event) { - if((/over|enter/).test(event.type) && cache.event && (/out|leave/).test(cache.event.type) && - options.show.target.add(event.target).length === options.show.target.length && - tooltip.has(event.relatedTarget).length) { - return this; - } - - // Cache event - cache.event = $.event.fix(event); - } - - // If we're currently waiting and we've just hidden... stop it - this.waiting && !state && (this.hiddenDuringWait = TRUE); - - // Render the tooltip if showing and it isn't already - if(!this.rendered) { return state ? this.render(1) : this; } - else if(this.destroyed || this.disabled) { return this; } - - var type = state ? 'show' : 'hide', - opts = this.options[type], - otherOpts = this.options[ !state ? 'show' : 'hide' ], - posOptions = this.options.position, - contentOptions = this.options.content, - width = this.tooltip.css('width'), - visible = this.tooltip.is(':visible'), - animate = state || opts.target.length === 1, - sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target, - identicalState, allow, showEvent, delay, after; - - // Detect state if valid one isn't provided - if((typeof state).search('boolean|number')) { state = !visible; } - - // Check if the tooltip is in an identical state to the new would-be state - identicalState = !tooltip.is(':animated') && visible === state && sameTarget; - - // Fire tooltip(show/hide) event and check if destroyed - allow = !identicalState ? !!this._trigger(type, [90]) : NULL; - - // Check to make sure the tooltip wasn't destroyed in the callback - if(this.destroyed) { return this; } - - // If the user didn't stop the method prematurely and we're showing the tooltip, focus it - if(allow !== FALSE && state) { this.focus(event); } - - // If the state hasn't changed or the user stopped it, return early - if(!allow || identicalState) { return this; } - - // Set ARIA hidden attribute - $.attr(tooltip[0], 'aria-hidden', !!!state); - - // Execute state specific properties - if(state) { - // Store show origin coordinates - this.mouse && (cache.origin = $.event.fix(this.mouse)); - - // Update tooltip content & title if it's a dynamic function - if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); } - if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); } - - // Cache mousemove events for positioning purposes (if not already tracking) - if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) { - $(document).bind('mousemove.'+NAMESPACE, this._storeMouse); - trackingBound = TRUE; - } - - // Update the tooltip position (set width first to prevent viewport/max-width issues) - if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); } - this.reposition(event, arguments[2]); - if(!width) { tooltip.css('width', ''); } - - // Hide other tooltips if tooltip is solo - if(!!opts.solo) { - (typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo)) - .not(tooltip).not(opts.target).qtip('hide', $.Event('tooltipsolo')); - } - } - else { - // Clear show timer if we're hiding - clearTimeout(this.timers.show); - - // Remove cached origin on hide - delete cache.origin; - - // Remove mouse tracking event if not needed (all tracking qTips are hidden) - if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) { - $(document).unbind('mousemove.'+NAMESPACE); - trackingBound = FALSE; - } - - // Blur the tooltip - this.blur(event); - } - - // Define post-animation, state specific properties - after = $.proxy(function() { - if(state) { - // Prevent antialias from disappearing in IE by removing filter - if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); } - - // Remove overflow setting to prevent tip bugs - tooltip.css('overflow', ''); - - // Autofocus elements if enabled - if('string' === typeof opts.autofocus) { - $(this.options.show.autofocus, tooltip).focus(); - } - - // If set, hide tooltip when inactive for delay period - this.options.show.target.trigger('qtip-'+this.id+'-inactive'); - } - else { - // Reset CSS states - tooltip.css({ - display: '', - visibility: '', - opacity: '', - left: '', - top: '' - }); - } - - // tooltipvisible/tooltiphidden events - this._trigger(state ? 'visible' : 'hidden'); - }, this); - - // If no effect type is supplied, use a simple toggle - if(opts.effect === FALSE || animate === FALSE) { - tooltip[ type ](); - after(); - } - - // Use custom function if provided - else if($.isFunction(opts.effect)) { - tooltip.stop(1, 1); - opts.effect.call(tooltip, this); - tooltip.queue('fx', function(n) { - after(); n(); - }); - } - - // Use basic fade function by default - else { tooltip.fadeTo(90, state ? 1 : 0, after); } - - // If inactive hide method is set, active it - if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); } - - return this; -}; - -PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); }; - -PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); }; -;PROTOTYPE.focus = function(event) { - if(!this.rendered || this.destroyed) { return this; } - - var qtips = $(SELECTOR), - tooltip = this.tooltip, - curIndex = parseInt(tooltip[0].style.zIndex, 10), - newIndex = QTIP.zindex + qtips.length, - focusedElem; - - // Only update the z-index if it has changed and tooltip is not already focused - if(!tooltip.hasClass(CLASS_FOCUS)) { - // tooltipfocus event - if(this._trigger('focus', [newIndex], event)) { - // Only update z-index's if they've changed - if(curIndex !== newIndex) { - // Reduce our z-index's and keep them properly ordered - qtips.each(function() { - if(this.style.zIndex > curIndex) { - this.style.zIndex = this.style.zIndex - 1; - } - }); - - // Fire blur event for focused tooltip - qtips.filter('.' + CLASS_FOCUS).qtip('blur', event); - } - - // Set the new z-index - tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; - } - } - - return this; -}; - -PROTOTYPE.blur = function(event) { - if(!this.rendered || this.destroyed) { return this; } - - // Set focused status to FALSE - this.tooltip.removeClass(CLASS_FOCUS); - - // tooltipblur event - this._trigger('blur', [ this.tooltip.css('zIndex') ], event); - - return this; -}; -;PROTOTYPE.disable = function(state) { - if(this.destroyed) { return this; } - - // If 'toggle' is passed, toggle the current state - if(state === 'toggle') { - state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled); - } - - // Disable if no state passed - else if('boolean' !== typeof state) { - state = TRUE; - } - - if(this.rendered) { - this.tooltip.toggleClass(CLASS_DISABLED, state) - .attr('aria-disabled', state); - } - - this.disabled = !!state; - - return this; -}; - -PROTOTYPE.enable = function() { return this.disable(FALSE); }; -;PROTOTYPE._createButton = function() -{ - var self = this, - elements = this.elements, - tooltip = elements.tooltip, - button = this.options.content.button, - isString = typeof button === 'string', - close = isString ? button : 'Close tooltip'; - - if(elements.button) { elements.button.remove(); } - - // Use custom button if one was supplied by user, else use default - if(button.jquery) { - elements.button = button; - } - else { - elements.button = $('', { - 'class': 'qtip-close ' + (this.options.style.widget ? '' : NAMESPACE+'-icon'), - 'title': close, - 'aria-label': close - }) - .prepend( - $('', { - 'class': 'ui-icon ui-icon-close', - 'html': '×' - }) - ); - } - - // Create button and setup attributes - elements.button.appendTo(elements.titlebar || tooltip) - .attr('role', 'button') - .click(function(event) { - if(!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); } - return FALSE; - }); -}; - -PROTOTYPE._updateButton = function(button) -{ - // Make sure tooltip is rendered and if not, return - if(!this.rendered) { return FALSE; } - - var elem = this.elements.button; - if(button) { this._createButton(); } - else { elem.remove(); } -}; -;// Widget class creator -function createWidgetClass(cls) { - return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' '); -} - -// Widget class setter method -PROTOTYPE._setWidget = function() -{ - var on = this.options.style.widget, - elements = this.elements, - tooltip = elements.tooltip, - disabled = tooltip.hasClass(CLASS_DISABLED); - - tooltip.removeClass(CLASS_DISABLED); - CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled'; - tooltip.toggleClass(CLASS_DISABLED, disabled); - - tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on); - - if(elements.content) { - elements.content.toggleClass( createWidgetClass('content'), on); - } - if(elements.titlebar) { - elements.titlebar.toggleClass( createWidgetClass('header'), on); - } - if(elements.button) { - elements.button.toggleClass(NAMESPACE+'-icon', !on); - } -}; -;function delay(callback, duration) { - // If tooltip has displayed, start hide timer - if(duration > 0) { - return setTimeout( - $.proxy(callback, this), duration - ); - } - else{ callback.call(this); } -} - -function showMethod(event) { - if(this.tooltip.hasClass(CLASS_DISABLED)) { return; } - - // Clear hide timers - clearTimeout(this.timers.show); - clearTimeout(this.timers.hide); - - // Start show timer - this.timers.show = delay.call(this, - function() { this.toggle(TRUE, event); }, - this.options.show.delay - ); -} - -function hideMethod(event) { - if(this.tooltip.hasClass(CLASS_DISABLED) || this.destroyed) { return; } - - // Check if new target was actually the tooltip element - var relatedTarget = $(event.relatedTarget), - ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.tooltip[0], - ontoTarget = relatedTarget[0] === this.options.show.target[0]; - - // Clear timers and stop animation queue - clearTimeout(this.timers.show); - clearTimeout(this.timers.hide); - - // Prevent hiding if tooltip is fixed and event target is the tooltip. - // Or if mouse positioning is enabled and cursor momentarily overlaps - if(this !== relatedTarget[0] && - (this.options.position.target === 'mouse' && ontoTooltip) || - (this.options.hide.fixed && ( - (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)) - )) - { - try { - event.preventDefault(); - event.stopImmediatePropagation(); - } catch(e) {} - - return; - } - - // If tooltip has displayed, start hide timer - this.timers.hide = delay.call(this, - function() { this.toggle(FALSE, event); }, - this.options.hide.delay, - this - ); -} - -function inactiveMethod(event) { - if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return; } - - // Clear timer - clearTimeout(this.timers.inactive); - - this.timers.inactive = delay.call(this, - function(){ this.hide(event); }, - this.options.hide.inactive - ); -} - -function repositionMethod(event) { - if(this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } -} - -// Store mouse coordinates -PROTOTYPE._storeMouse = function(event) { - (this.mouse = $.event.fix(event)).type = 'mousemove'; - return this; -}; - -// Bind events -PROTOTYPE._bind = function(targets, events, method, suffix, context) { - if(!targets || !method || !events.length) { return; } - var ns = '.' + this._id + (suffix ? '-'+suffix : ''); - $(targets).bind( - (events.split ? events : events.join(ns + ' ')) + ns, - $.proxy(method, context || this) - ); - return this; -}; -PROTOTYPE._unbind = function(targets, suffix) { - targets && $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : '')); - return this; -}; - -// Global delegation helper -function delegate(selector, events, method) { - $(document.body).delegate(selector, - (events.split ? events : events.join('.'+NAMESPACE + ' ')) + '.'+NAMESPACE, - function() { - var api = QTIP.api[ $.attr(this, ATTR_ID) ]; - api && !api.disabled && method.apply(api, arguments); - } - ); -} -// Event trigger -PROTOTYPE._trigger = function(type, args, event) { - var callback = $.Event('tooltip'+type); - callback.originalEvent = (event && $.extend({}, event)) || this.cache.event || NULL; - - this.triggering = type; - this.tooltip.trigger(callback, [this].concat(args || [])); - this.triggering = FALSE; - - return !callback.isDefaultPrevented(); -}; - -PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTargets, hideTargets, showMethod, hideMethod) { - // Get tasrgets that lye within both - var similarTargets = showTargets.filter( hideTargets ).add( hideTargets.filter(showTargets) ), - toggleEvents = []; - - // If hide and show targets are the same... - if(similarTargets.length) { - - // Filter identical show/hide events - $.each(hideEvents, function(i, type) { - var showIndex = $.inArray(type, showEvents); - - // Both events are identical, remove from both hide and show events - // and append to toggleEvents - showIndex > -1 && toggleEvents.push( showEvents.splice( showIndex, 1 )[0] ); - }); - - // Toggle events are special case of identical show/hide events, which happen in sequence - if(toggleEvents.length) { - // Bind toggle events to the similar targets - this._bind(similarTargets, toggleEvents, function(event) { - var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false; - (state ? hideMethod : showMethod).call(this, event); - }); - - // Remove the similar targets from the regular show/hide bindings - showTargets = showTargets.not(similarTargets); - hideTargets = hideTargets.not(similarTargets); - } - } - - // Apply show/hide/toggle events - this._bind(showTargets, showEvents, showMethod); - this._bind(hideTargets, hideEvents, hideMethod); -}; - -PROTOTYPE._assignInitialEvents = function(event) { - var options = this.options, - showTarget = options.show.target, - hideTarget = options.hide.target, - showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], - hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; - - // Catch remove/removeqtip events on target element to destroy redundant tooltips - this._bind(this.elements.target, ['remove', 'removeqtip'], function(event) { - this.destroy(true); - }, 'destroy'); - - /* - * Make sure hoverIntent functions properly by using mouseleave as a hide event if - * mouseenter/mouseout is used for show.event, even if it isn't in the users options. - */ - if(/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|leave)/i.test(options.hide.event)) { - hideEvents.push('mouseleave'); - } - - /* - * Also make sure initial mouse targetting works correctly by caching mousemove coords - * on show targets before the tooltip has rendered. Also set onTarget when triggered to - * keep mouse tracking working. - */ - this._bind(showTarget, 'mousemove', function(event) { - this._storeMouse(event); - this.cache.onTarget = TRUE; - }); - - // Define hoverIntent function - function hoverIntent(event) { - // Only continue if tooltip isn't disabled - if(this.disabled || this.destroyed) { return FALSE; } - - // Cache the event data - this.cache.event = event && $.event.fix(event); - this.cache.target = event && $(event.target); - - // Start the event sequence - clearTimeout(this.timers.show); - this.timers.show = delay.call(this, - function() { this.render(typeof event === 'object' || options.show.ready); }, - options.prerender ? 0 : options.show.delay - ); - } - - // Filter and bind events - this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() { - if(!this.timers) { return FALSE; } - clearTimeout(this.timers.show); - }); - - // Prerendering is enabled, create tooltip now - if(options.show.ready || options.prerender) { hoverIntent.call(this, event); } -}; - -// Event assignment method -PROTOTYPE._assignEvents = function() { - var self = this, - options = this.options, - posOptions = options.position, - - tooltip = this.tooltip, - showTarget = options.show.target, - hideTarget = options.hide.target, - containerTarget = posOptions.container, - viewportTarget = posOptions.viewport, - documentTarget = $(document), - bodyTarget = $(document.body), - windowTarget = $(window), - - showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], - hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; - - - // Assign passed event callbacks - $.each(options.events, function(name, callback) { - self._bind(tooltip, name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name], callback, null, tooltip); - }); - - // Hide tooltips when leaving current window/frame (but not select/option elements) - if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') { - this._bind(documentTarget, ['mouseout', 'blur'], function(event) { - if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { - this.hide(event); - } - }); - } - - // Enable hide.fixed by adding appropriate class - if(options.hide.fixed) { - hideTarget = hideTarget.add( tooltip.addClass(CLASS_FIXED) ); - } - - /* - * Make sure hoverIntent functions properly by using mouseleave to clear show timer if - * mouseenter/mouseout is used for show.event, even if it isn't in the users options. - */ - else if(/mouse(over|enter)/i.test(options.show.event)) { - this._bind(hideTarget, 'mouseleave', function() { - clearTimeout(this.timers.show); - }); - } - - // Hide tooltip on document mousedown if unfocus events are enabled - if(('' + options.hide.event).indexOf('unfocus') > -1) { - this._bind(containerTarget.closest('html'), ['mousedown', 'touchstart'], function(event) { - var elem = $(event.target), - enabled = this.rendered && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0, - isAncestor = elem.parents(SELECTOR).filter(this.tooltip[0]).length > 0; - - if(elem[0] !== this.target[0] && elem[0] !== this.tooltip[0] && !isAncestor && - !this.target.has(elem[0]).length && enabled - ) { - this.hide(event); - } - }); - } - - // Check if the tooltip hides when inactive - if('number' === typeof options.hide.inactive) { - // Bind inactive method to show target(s) as a custom event - this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod, 'inactive'); - - // Define events which reset the 'inactive' event handler - this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod); - } - - // Filter and bind events - this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod); - - // Mouse movement bindings - this._bind(showTarget.add(tooltip), 'mousemove', function(event) { - // Check if the tooltip hides when mouse is moved a certain distance - if('number' === typeof options.hide.distance) { - var origin = this.cache.origin || {}, - limit = this.options.hide.distance, - abs = Math.abs; - - // Check if the movement has gone beyond the limit, and hide it if so - if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) { - this.hide(event); - } - } - - // Cache mousemove coords on show targets - this._storeMouse(event); - }); - - // Mouse positioning events - if(posOptions.target === 'mouse') { - // If mouse adjustment is on... - if(posOptions.adjust.mouse) { - // Apply a mouseleave event so we don't get problems with overlapping - if(options.hide.event) { - // Track if we're on the target or not - this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) { - if(!this.cache) {return FALSE; } - this.cache.onTarget = event.type === 'mouseenter'; - }); - } - - // Update tooltip position on mousemove - this._bind(documentTarget, 'mousemove', function(event) { - // Update the tooltip position only if the tooltip is visible and adjustment is enabled - if(this.rendered && this.cache.onTarget && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) { - this.reposition(event); - } - }); - } - } - - // Adjust positions of the tooltip on window resize if enabled - if(posOptions.adjust.resize || viewportTarget.length) { - this._bind( $.event.special.resize ? viewportTarget : windowTarget, 'resize', repositionMethod ); - } - - // Adjust tooltip position on scroll of the window or viewport element if present - if(posOptions.adjust.scroll) { - this._bind( windowTarget.add(posOptions.container), 'scroll', repositionMethod ); - } -}; - -// Un-assignment method -PROTOTYPE._unassignEvents = function() { - var options = this.options, - showTargets = options.show.target, - hideTargets = options.hide.target, - targets = $.grep([ - this.elements.target[0], - this.rendered && this.tooltip[0], - options.position.container[0], - options.position.viewport[0], - options.position.container.closest('html')[0], // unfocus - window, - document - ], function(i) { - return typeof i === 'object'; - }); - - // Add show and hide targets if they're valid - if(showTargets && showTargets.toArray) { - targets = targets.concat(showTargets.toArray()); - } - if(hideTargets && hideTargets.toArray) { - targets = targets.concat(hideTargets.toArray()); - } - - // Unbind the events - this._unbind(targets) - ._unbind(targets, 'destroy') - ._unbind(targets, 'inactive'); -}; - -// Apply common event handlers using delegate (avoids excessive .bind calls!) -$(function() { - delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) { - var state = event.type === 'mouseenter', - tooltip = $(event.currentTarget), - target = $(event.relatedTarget || event.target), - options = this.options; - - // On mouseenter... - if(state) { - // Focus the tooltip on mouseenter (z-index stacking) - this.focus(event); - - // Clear hide timer on tooltip hover to prevent it from closing - tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide); - } - - // On mouseleave... - else { - // When mouse tracking is enabled, hide when we leave the tooltip and not onto the show target (if a hide event is set) - if(options.position.target === 'mouse' && options.position.adjust.mouse && - options.hide.event && options.show.target && !target.closest(options.show.target[0]).length) { - this.hide(event); - } - } - - // Add hover class - tooltip.toggleClass(CLASS_HOVER, state); - }); - - // Define events which reset the 'inactive' event handler - delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod); -}); -;// Initialization method -function init(elem, id, opts) { - var obj, posOptions, attr, config, title, - - // Setup element references - docBody = $(document.body), - - // Use document body instead of document element if needed - newTarget = elem[0] === document ? docBody : elem, - - // Grab metadata from element if plugin is present - metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL, - - // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise - metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL, - - // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method, - html5 = elem.data(opts.metadata.name || 'qtipopts'); - - // If we don't get an object returned attempt to parse it manualyl without parseJSON - try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {} - - // Merge in and sanitize metadata - config = $.extend(TRUE, {}, QTIP.defaults, opts, - typeof html5 === 'object' ? sanitizeOptions(html5) : NULL, - sanitizeOptions(metadata5 || metadata)); - - // Re-grab our positioning options now we've merged our metadata and set id to passed value - posOptions = config.position; - config.id = id; - - // Setup missing content if none is detected - if('boolean' === typeof config.content.text) { - attr = elem.attr(config.content.attr); - - // Grab from supplied attribute if available - if(config.content.attr !== FALSE && attr) { config.content.text = attr; } - - // No valid content was found, abort render - else { return FALSE; } - } - - // Setup target options - if(!posOptions.container.length) { posOptions.container = docBody; } - if(posOptions.target === FALSE) { posOptions.target = newTarget; } - if(config.show.target === FALSE) { config.show.target = newTarget; } - if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); } - if(config.hide.target === FALSE) { config.hide.target = newTarget; } - if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; } - - // Ensure we only use a single container - posOptions.container = posOptions.container.eq(0); - - // Convert position corner values into x and y strings - posOptions.at = new CORNER(posOptions.at, TRUE); - posOptions.my = new CORNER(posOptions.my); - - // Destroy previous tooltip if overwrite is enabled, or skip element if not - if(elem.data(NAMESPACE)) { - if(config.overwrite) { - elem.qtip('destroy', true); - } - else if(config.overwrite === FALSE) { - return FALSE; - } - } - - // Add has-qtip attribute - elem.attr(ATTR_HAS, id); - - // Remove title attribute and store it if present - if(config.suppress && (title = elem.attr('title'))) { - // Final attr call fixes event delegatiom and IE default tooltip showing problem - elem.removeAttr('title').attr(oldtitle, title).attr('title', ''); - } - - // Initialize the tooltip and add API reference - obj = new QTip(elem, config, id, !!attr); - elem.data(NAMESPACE, obj); - - return obj; -} - -// jQuery $.fn extension method -QTIP = $.fn.qtip = function(options, notation, newValue) -{ - var command = ('' + options).toLowerCase(), // Parse command - returned = NULL, - args = $.makeArray(arguments).slice(1), - event = args[args.length - 1], - opts = this[0] ? $.data(this[0], NAMESPACE) : NULL; - - // Check for API request - if((!arguments.length && opts) || command === 'api') { - return opts; - } - - // Execute API command if present - else if('string' === typeof options) { - this.each(function() { - var api = $.data(this, NAMESPACE); - if(!api) { return TRUE; } - - // Cache the event if possible - if(event && event.timeStamp) { api.cache.event = event; } - - // Check for specific API commands - if(notation && (command === 'option' || command === 'options')) { - if(newValue !== undefined || $.isPlainObject(notation)) { - api.set(notation, newValue); - } - else { - returned = api.get(notation); - return FALSE; - } - } - - // Execute API command - else if(api[command]) { - api[command].apply(api, args); - } - }); - - return returned !== NULL ? returned : this; - } - - // No API commands. validate provided options and setup qTips - else if('object' === typeof options || !arguments.length) { - // Sanitize options first - opts = sanitizeOptions($.extend(TRUE, {}, options)); - - return this.each(function(i) { - var api, id; - - // Find next available ID, or use custom ID if provided - id = $.isArray(opts.id) ? opts.id[i] : opts.id; - id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id; - - // Initialize the qTip and re-grab newly sanitized options - api = init($(this), id, opts); - if(api === FALSE) { return TRUE; } - else { QTIP.api[id] = api; } - - // Initialize plugins - $.each(PLUGINS, function() { - if(this.initialize === 'initialize') { this(api); } - }); - - // Assign initial pre-render events - api._assignInitialEvents(event); - }); - } -}; - -// Expose class -$.qtip = QTip; - -// Populated in render method -QTIP.api = {}; -;$.each({ - /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */ - attr: function(attr, val) { - if(this.length) { - var self = this[0], - title = 'title', - api = $.data(self, 'qtip'); - - if(attr === title && api && 'object' === typeof api && api.options.suppress) { - if(arguments.length < 2) { - return $.attr(self, oldtitle); - } - - // If qTip is rendered and title was originally used as content, update it - if(api && api.options.content.attr === title && api.cache.attr) { - api.set('content.text', val); - } - - // Use the regular attr method to set, then cache the result - return this.attr(oldtitle, val); - } - } - - return $.fn['attr'+replaceSuffix].apply(this, arguments); - }, - - /* Allow clone to correctly retrieve cached title attributes */ - clone: function(keepData) { - var titles = $([]), title = 'title', - - // Clone our element using the real clone method - elems = $.fn['clone'+replaceSuffix].apply(this, arguments); - - // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false - if(!keepData) { - elems.filter('['+oldtitle+']').attr('title', function() { - return $.attr(this, oldtitle); - }) - .removeAttr(oldtitle); - } - - return elems; - } -}, function(name, func) { - if(!func || $.fn[name+replaceSuffix]) { return TRUE; } - - var old = $.fn[name+replaceSuffix] = $.fn[name]; - $.fn[name] = function() { - return func.apply(this, arguments) || old.apply(this, arguments); - }; -}); - -/* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar). - * This snippet is taken directly from jQuery UI source code found here: - * http://code.jquery.com/ui/jquery-ui-git.js - */ -if(!$.ui) { - $['cleanData'+replaceSuffix] = $.cleanData; - $.cleanData = function( elems ) { - for(var i = 0, elem; (elem = $( elems[i] )).length; i++) { - if(elem.attr(ATTR_HAS)) { - try { elem.triggerHandler('removeqtip'); } - catch( e ) {} - } - } - $['cleanData'+replaceSuffix].apply(this, arguments); - }; -} -;// qTip version -QTIP.version = '2.2.1'; - -// Base ID for all qTips -QTIP.nextid = 0; - -// Inactive events array -QTIP.inactiveEvents = INACTIVE_EVENTS; - -// Base z-index for all qTips -QTIP.zindex = 15000; - -// Define configuration defaults -QTIP.defaults = { - prerender: FALSE, - id: FALSE, - overwrite: TRUE, - suppress: TRUE, - content: { - text: TRUE, - attr: 'title', - title: FALSE, - button: FALSE - }, - position: { - my: 'top left', - at: 'bottom right', - target: FALSE, - container: FALSE, - viewport: FALSE, - adjust: { - x: 0, y: 0, - mouse: TRUE, - scroll: TRUE, - resize: TRUE, - method: 'flipinvert flipinvert' - }, - effect: function(api, pos, viewport) { - $(this).animate(pos, { - duration: 200, - queue: FALSE - }); - } - }, - show: { - target: FALSE, - event: 'mouseenter', - effect: TRUE, - delay: 90, - solo: FALSE, - ready: FALSE, - autofocus: FALSE - }, - hide: { - target: FALSE, - event: 'mouseleave', - effect: TRUE, - delay: 0, - fixed: FALSE, - inactive: FALSE, - leave: 'window', - distance: FALSE - }, - style: { - classes: '', - widget: FALSE, - width: FALSE, - height: FALSE, - def: TRUE - }, - events: { - render: NULL, - move: NULL, - show: NULL, - hide: NULL, - toggle: NULL, - visible: NULL, - hidden: NULL, - focus: NULL, - blur: NULL - } -}; -;var TIP, - -// .bind()/.on() namespace -TIPNS = '.qtip-tip', - -// Common CSS strings -MARGIN = 'margin', -BORDER = 'border', -COLOR = 'color', -BG_COLOR = 'background-color', -TRANSPARENT = 'transparent', -IMPORTANT = ' !important', - -// Check if the browser supports elements -HASCANVAS = !!document.createElement('canvas').getContext, - -// Invalid colour values used in parseColours() -INVALID = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i; - -// Camel-case method, taken from jQuery source -// http://code.jquery.com/jquery-1.8.0.js -function camel(s) { return s.charAt(0).toUpperCase() + s.slice(1); } - -/* - * Modified from Modernizr's testPropsAll() - * http://modernizr.com/downloads/modernizr-latest.js - */ -var cssProps = {}, cssPrefixes = ["Webkit", "O", "Moz", "ms"]; -function vendorCss(elem, prop) { - var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), - props = (prop + ' ' + cssPrefixes.join(ucProp + ' ') + ucProp).split(' '), - cur, val, i = 0; - - // If the property has already been mapped... - if(cssProps[prop]) { return elem.css(cssProps[prop]); } - - while((cur = props[i++])) { - if((val = elem.css(cur)) !== undefined) { - return cssProps[prop] = cur, val; - } - } -} - -// Parse a given elements CSS property into an int -function intCss(elem, prop) { - return Math.ceil(parseFloat(vendorCss(elem, prop))); -} - - -// VML creation (for IE only) -if(!HASCANVAS) { - var createVML = function(tag, props, style) { - return ''; - }; -} - -// Canvas only definitions -else { - var PIXEL_RATIO = window.devicePixelRatio || 1, - BACKING_STORE_RATIO = (function() { - var context = document.createElement('canvas').getContext('2d'); - return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || - context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || 1; - }()), - SCALE = PIXEL_RATIO / BACKING_STORE_RATIO; -} - - -function Tip(qtip, options) { - this._ns = 'tip'; - this.options = options; - this.offset = options.offset; - this.size = [ options.width, options.height ]; - - // Initialize - this.init( (this.qtip = qtip) ); -} - -$.extend(Tip.prototype, { - init: function(qtip) { - var context, tip; - - // Create tip element and prepend to the tooltip - tip = this.element = qtip.elements.tip = $('
', { 'class': NAMESPACE+'-tip' }).prependTo(qtip.tooltip); - - // Create tip drawing element(s) - if(HASCANVAS) { - // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()! - context = $('').appendTo(this.element)[0].getContext('2d'); - - // Setup constant parameters - context.lineJoin = 'miter'; - context.miterLimit = 100000; - context.save(); - } - else { - context = createVML('shape', 'coordorigin="0,0"', 'position:absolute;'); - this.element.html(context + context); - - // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML - qtip._bind( $('*', tip).add(tip), ['click', 'mousedown'], function(event) { event.stopPropagation(); }, this._ns); - } - - // Bind update events - qtip._bind(qtip.tooltip, 'tooltipmove', this.reposition, this._ns, this); - - // Create it - this.create(); - }, - - _swapDimensions: function() { - this.size[0] = this.options.height; - this.size[1] = this.options.width; - }, - _resetDimensions: function() { - this.size[0] = this.options.width; - this.size[1] = this.options.height; - }, - - _useTitle: function(corner) { - var titlebar = this.qtip.elements.titlebar; - return titlebar && ( - corner.y === TOP || (corner.y === CENTER && this.element.position().top + (this.size[1] / 2) + this.options.offset < titlebar.outerHeight(TRUE)) - ); - }, - - _parseCorner: function(corner) { - var my = this.qtip.options.position.my; - - // Detect corner and mimic properties - if(corner === FALSE || my === FALSE) { - corner = FALSE; - } - else if(corner === TRUE) { - corner = new CORNER( my.string() ); - } - else if(!corner.string) { - corner = new CORNER(corner); - corner.fixed = TRUE; - } - - return corner; - }, - - _parseWidth: function(corner, side, use) { - var elements = this.qtip.elements, - prop = BORDER + camel(side) + 'Width'; - - return (use ? intCss(use, prop) : ( - intCss(elements.content, prop) || - intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || - intCss(elements.tooltip, prop) - )) || 0; - }, - - _parseRadius: function(corner) { - var elements = this.qtip.elements, - prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius'; - - return BROWSER.ie < 9 ? 0 : - intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || - intCss(elements.tooltip, prop) || 0; - }, - - _invalidColour: function(elem, prop, compare) { - var val = elem.css(prop); - return !val || (compare && val === elem.css(compare)) || INVALID.test(val) ? FALSE : val; - }, - - _parseColours: function(corner) { - var elements = this.qtip.elements, - tip = this.element.css('cssText', ''), - borderSide = BORDER + camel(corner[ corner.precedance ]) + camel(COLOR), - colorElem = this._useTitle(corner) && elements.titlebar || elements.content, - css = this._invalidColour, color = []; - - // Attempt to detect the background colour from various elements, left-to-right precedance - color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) || - css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR); - - // Attempt to detect the correct border side colour from various elements, left-to-right precedance - color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) || - css(elements.content, borderSide, COLOR) || css(elements.tooltip, borderSide, COLOR) || elements.tooltip.css(borderSide); - - // Reset background and border colours - $('*', tip).add(tip).css('cssText', BG_COLOR+':'+TRANSPARENT+IMPORTANT+';'+BORDER+':0'+IMPORTANT+';'); - - return color; - }, - - _calculateSize: function(corner) { - var y = corner.precedance === Y, - width = this.options['width'], - height = this.options['height'], - isCenter = corner.abbrev() === 'c', - base = (y ? width: height) * (isCenter ? 0.5 : 1), - pow = Math.pow, - round = Math.round, - bigHyp, ratio, result, - - smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ), - hyp = [ (this.border / base) * smallHyp, (this.border / height) * smallHyp ]; - - hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(this.border, 2) ); - hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(this.border, 2) ); - - bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]); - ratio = bigHyp / smallHyp; - - result = [ round(ratio * width), round(ratio * height) ]; - return y ? result : result.reverse(); - }, - - // Tip coordinates calculator - _calculateTip: function(corner, size, scale) { - scale = scale || 1; - size = size || this.size; - - var width = size[0] * scale, - height = size[1] * scale, - width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2), - - // Define tip coordinates in terms of height and width values - tips = { - br: [0,0, width,height, width,0], - bl: [0,0, width,0, 0,height], - tr: [0,height, width,0, width,height], - tl: [0,0, 0,height, width,height], - tc: [0,height, width2,0, width,height], - bc: [0,0, width,0, width2,height], - rc: [0,0, width,height2, 0,height], - lc: [width,0, width,height, 0,height2] - }; - - // Set common side shapes - tips.lt = tips.br; tips.rt = tips.bl; - tips.lb = tips.tr; tips.rb = tips.tl; - - return tips[ corner.abbrev() ]; - }, - - // Tip coordinates drawer (canvas) - _drawCoords: function(context, coords) { - context.beginPath(); - context.moveTo(coords[0], coords[1]); - context.lineTo(coords[2], coords[3]); - context.lineTo(coords[4], coords[5]); - context.closePath(); - }, - - create: function() { - // Determine tip corner - var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner); - - // If we have a tip corner... - if( (this.enabled = !!this.corner && this.corner.abbrev() !== 'c') ) { - // Cache it - this.qtip.cache.corner = c.clone(); - - // Create it - this.update(); - } - - // Toggle tip element - this.element.toggle(this.enabled); - - return this.corner; - }, - - update: function(corner, position) { - if(!this.enabled) { return this; } - - var elements = this.qtip.elements, - tip = this.element, - inner = tip.children(), - options = this.options, - curSize = this.size, - mimic = options.mimic, - round = Math.round, - color, precedance, context, - coords, bigCoords, translate, newSize, border, BACKING_STORE_RATIO; - - // Re-determine tip if not already set - if(!corner) { corner = this.qtip.cache.corner || this.corner; } - - // Use corner property if we detect an invalid mimic value - if(mimic === FALSE) { mimic = corner; } - - // Otherwise inherit mimic properties from the corner object as necessary - else { - mimic = new CORNER(mimic); - mimic.precedance = corner.precedance; - - if(mimic.x === 'inherit') { mimic.x = corner.x; } - else if(mimic.y === 'inherit') { mimic.y = corner.y; } - else if(mimic.x === mimic.y) { - mimic[ corner.precedance ] = corner[ corner.precedance ]; - } - } - precedance = mimic.precedance; - - // Ensure the tip width.height are relative to the tip position - if(corner.precedance === X) { this._swapDimensions(); } - else { this._resetDimensions(); } - - // Update our colours - color = this.color = this._parseColours(corner); - - // Detect border width, taking into account colours - if(color[1] !== TRANSPARENT) { - // Grab border width - border = this.border = this._parseWidth(corner, corner[corner.precedance]); - - // If border width isn't zero, use border color as fill if it's not invalid (1.0 style tips) - if(options.border && border < 1 && !INVALID.test(color[1])) { color[0] = color[1]; } - - // Set border width (use detected border width if options.border is true) - this.border = border = options.border !== TRUE ? options.border : border; - } - - // Border colour was invalid, set border to zero - else { this.border = border = 0; } - - // Determine tip size - newSize = this.size = this._calculateSize(corner); - tip.css({ - width: newSize[0], - height: newSize[1], - lineHeight: newSize[1]+'px' - }); - - // Calculate tip translation - if(corner.precedance === Y) { - translate = [ - round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] - curSize[0] - border : (newSize[0] - curSize[0]) / 2), - round(mimic.y === TOP ? newSize[1] - curSize[1] : 0) - ]; - } - else { - translate = [ - round(mimic.x === LEFT ? newSize[0] - curSize[0] : 0), - round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] - curSize[1] - border : (newSize[1] - curSize[1]) / 2) - ]; - } - - // Canvas drawing implementation - if(HASCANVAS) { - // Grab canvas context and clear/save it - context = inner[0].getContext('2d'); - context.restore(); context.save(); - context.clearRect(0,0,6000,6000); - - // Calculate coordinates - coords = this._calculateTip(mimic, curSize, SCALE); - bigCoords = this._calculateTip(mimic, this.size, SCALE); - - // Set the canvas size using calculated size - inner.attr(WIDTH, newSize[0] * SCALE).attr(HEIGHT, newSize[1] * SCALE); - inner.css(WIDTH, newSize[0]).css(HEIGHT, newSize[1]); - - // Draw the outer-stroke tip - this._drawCoords(context, bigCoords); - context.fillStyle = color[1]; - context.fill(); - - // Draw the actual tip - context.translate(translate[0] * SCALE, translate[1] * SCALE); - this._drawCoords(context, coords); - context.fillStyle = color[0]; - context.fill(); - } - - // VML (IE Proprietary implementation) - else { - // Calculate coordinates - coords = this._calculateTip(mimic); - - // Setup coordinates string - coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2] + - ',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + ' xe'; - - // Setup VML-specific offset for pixel-perfection - translate[2] = border && /^(r|b)/i.test(corner.string()) ? - BROWSER.ie === 8 ? 2 : 1 : 0; - - // Set initial CSS - inner.css({ - coordsize: (newSize[0]+border) + ' ' + (newSize[1]+border), - antialias: ''+(mimic.string().indexOf(CENTER) > -1), - left: translate[0] - (translate[2] * Number(precedance === X)), - top: translate[1] - (translate[2] * Number(precedance === Y)), - width: newSize[0] + border, - height: newSize[1] + border - }) - .each(function(i) { - var $this = $(this); - - // Set shape specific attributes - $this[ $this.prop ? 'prop' : 'attr' ]({ - coordsize: (newSize[0]+border) + ' ' + (newSize[1]+border), - path: coords, - fillcolor: color[0], - filled: !!i, - stroked: !i - }) - .toggle(!!(border || i)); - - // Check if border is enabled and add stroke element - !i && $this.html( createVML( - 'stroke', 'weight="'+(border*2)+'px" color="'+color[1]+'" miterlimit="1000" joinstyle="miter"' - ) ); - }); - } - - // Opera bug #357 - Incorrect tip position - // https://github.com/Craga89/qTip2/issues/367 - window.opera && setTimeout(function() { - elements.tip.css({ - display: 'inline-block', - visibility: 'visible' - }); - }, 1); - - // Position if needed - if(position !== FALSE) { this.calculate(corner, newSize); } - }, - - calculate: function(corner, size) { - if(!this.enabled) { return FALSE; } - - var self = this, - elements = this.qtip.elements, - tip = this.element, - userOffset = this.options.offset, - isWidget = elements.tooltip.hasClass('ui-widget'), - position = { }, - precedance, corners; - - // Inherit corner if not provided - corner = corner || this.corner; - precedance = corner.precedance; - - // Determine which tip dimension to use for adjustment - size = size || this._calculateSize(corner); - - // Setup corners and offset array - corners = [ corner.x, corner.y ]; - if(precedance === X) { corners.reverse(); } - - // Calculate tip position - $.each(corners, function(i, side) { - var b, bc, br; - - if(side === CENTER) { - b = precedance === Y ? LEFT : TOP; - position[ b ] = '50%'; - position[MARGIN+'-' + b] = -Math.round(size[ precedance === Y ? 0 : 1 ] / 2) + userOffset; - } - else { - b = self._parseWidth(corner, side, elements.tooltip); - bc = self._parseWidth(corner, side, elements.content); - br = self._parseRadius(corner); - - position[ side ] = Math.max(-self.border, i ? bc : (userOffset + (br > b ? br : -b))); - } - }); - - // Adjust for tip size - position[ corner[precedance] ] -= size[ precedance === X ? 0 : 1 ]; - - // Set and return new position - tip.css({ margin: '', top: '', bottom: '', left: '', right: '' }).css(position); - return position; - }, - - reposition: function(event, api, pos, viewport) { - if(!this.enabled) { return; } - - var cache = api.cache, - newCorner = this.corner.clone(), - adjust = pos.adjusted, - method = api.options.position.adjust.method.split(' '), - horizontal = method[0], - vertical = method[1] || method[0], - shift = { left: FALSE, top: FALSE, x: 0, y: 0 }, - offset, css = {}, props; - - function shiftflip(direction, precedance, popposite, side, opposite) { - // Horizontal - Shift or flip method - if(direction === SHIFT && newCorner.precedance === precedance && adjust[side] && newCorner[popposite] !== CENTER) { - newCorner.precedance = newCorner.precedance === X ? Y : X; - } - else if(direction !== SHIFT && adjust[side]){ - newCorner[precedance] = newCorner[precedance] === CENTER ? - (adjust[side] > 0 ? side : opposite) : (newCorner[precedance] === side ? opposite : side); - } - } - - function shiftonly(xy, side, opposite) { - if(newCorner[xy] === CENTER) { - css[MARGIN+'-'+side] = shift[xy] = offset[MARGIN+'-'+side] - adjust[side]; - } - else { - props = offset[opposite] !== undefined ? - [ adjust[side], -offset[side] ] : [ -adjust[side], offset[side] ]; - - if( (shift[xy] = Math.max(props[0], props[1])) > props[0] ) { - pos[side] -= adjust[side]; - shift[side] = FALSE; - } - - css[ offset[opposite] !== undefined ? opposite : side ] = shift[xy]; - } - } - - // If our tip position isn't fixed e.g. doesn't adjust with viewport... - if(this.corner.fixed !== TRUE) { - // Perform shift/flip adjustments - shiftflip(horizontal, X, Y, LEFT, RIGHT); - shiftflip(vertical, Y, X, TOP, BOTTOM); - - // Update and redraw the tip if needed (check cached details of last drawn tip) - if(newCorner.string() !== cache.corner.string() || cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left) { - this.update(newCorner, FALSE); - } - } - - // Setup tip offset properties - offset = this.calculate(newCorner); - - // Readjust offset object to make it left/top - if(offset.right !== undefined) { offset.left = -offset.right; } - if(offset.bottom !== undefined) { offset.top = -offset.bottom; } - offset.user = this.offset; - - // Perform shift adjustments - if(shift.left = (horizontal === SHIFT && !!adjust.left)) { shiftonly(X, LEFT, RIGHT); } - if(shift.top = (vertical === SHIFT && !!adjust.top)) { shiftonly(Y, TOP, BOTTOM); } - - /* - * If the tip is adjusted in both dimensions, or in a - * direction that would cause it to be anywhere but the - * outer border, hide it! - */ - this.element.css(css).toggle( - !((shift.x && shift.y) || (newCorner.x === CENTER && shift.y) || (newCorner.y === CENTER && shift.x)) - ); - - // Adjust position to accomodate tip dimensions - pos.left -= offset.left.charAt ? offset.user : - horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left + this.border : 0; - pos.top -= offset.top.charAt ? offset.user : - vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top + this.border : 0; - - // Cache details - cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top; - cache.corner = newCorner.clone(); - }, - - destroy: function() { - // Unbind events - this.qtip._unbind(this.qtip.tooltip, this._ns); - - // Remove the tip element(s) - if(this.qtip.elements.tip) { - this.qtip.elements.tip.find('*') - .remove().end().remove(); - } - } -}); - -TIP = PLUGINS.tip = function(api) { - return new Tip(api, api.options.style.tip); -}; - -// Initialize tip on render -TIP.initialize = 'render'; - -// Setup plugin sanitization options -TIP.sanitize = function(options) { - if(options.style && 'tip' in options.style) { - var opts = options.style.tip; - if(typeof opts !== 'object') { opts = options.style.tip = { corner: opts }; } - if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; } - } -}; - -// Add new option checks for the plugin -CHECKS.tip = { - '^position.my|style.tip.(corner|mimic|border)$': function() { - // Make sure a tip can be drawn - this.create(); - - // Reposition the tooltip - this.qtip.reposition(); - }, - '^style.tip.(height|width)$': function(obj) { - // Re-set dimensions and redraw the tip - this.size = [ obj.width, obj.height ]; - this.update(); - - // Reposition the tooltip - this.qtip.reposition(); - }, - '^content.title|style.(classes|widget)$': function() { - this.update(); - } -}; - -// Extend original qTip defaults -$.extend(TRUE, QTIP.defaults, { - style: { - tip: { - corner: TRUE, - mimic: FALSE, - width: 6, - height: 6, - border: TRUE, - offset: 0 - } - } -}); -;PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight) -{ - var target = posOptions.target, - tooltip = api.elements.tooltip, - my = posOptions.my, - at = posOptions.at, - adjust = posOptions.adjust, - method = adjust.method.split(' '), - methodX = method[0], - methodY = method[1] || method[0], - viewport = posOptions.viewport, - container = posOptions.container, - cache = api.cache, - adjusted = { left: 0, top: 0 }, - fixed, newMy, containerOffset, containerStatic, - viewportWidth, viewportHeight, viewportScroll, viewportOffset; - - // If viewport is not a jQuery element, or it's the window/document, or no adjustment method is used... return - if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') { - return adjusted; - } - - // Cach container details - containerOffset = container.offset() || adjusted; - containerStatic = container.css('position') === 'static'; - - // Cache our viewport details - fixed = tooltip.css('position') === 'fixed'; - viewportWidth = viewport[0] === window ? viewport.width() : viewport.outerWidth(FALSE); - viewportHeight = viewport[0] === window ? viewport.height() : viewport.outerHeight(FALSE); - viewportScroll = { left: fixed ? 0 : viewport.scrollLeft(), top: fixed ? 0 : viewport.scrollTop() }; - viewportOffset = viewport.offset() || adjusted; - - // Generic calculation method - function calculate(side, otherSide, type, adjust, side1, side2, lengthName, targetLength, elemLength) { - var initialPos = position[side1], - mySide = my[side], - atSide = at[side], - isShift = type === SHIFT, - myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2, - atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2, - sideOffset = viewportScroll[side1] + viewportOffset[side1] - (containerStatic ? 0 : containerOffset[side1]), - overflow1 = sideOffset - initialPos, - overflow2 = initialPos + elemLength - (lengthName === WIDTH ? viewportWidth : viewportHeight) - sideOffset, - offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0); - - // shift - if(isShift) { - offset = (mySide === side1 ? 1 : -1) * myLength; - - // Adjust position but keep it within viewport dimensions - position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0; - position[side1] = Math.max( - -containerOffset[side1] + viewportOffset[side1], - initialPos - offset, - Math.min( - Math.max( - -containerOffset[side1] + viewportOffset[side1] + (lengthName === WIDTH ? viewportWidth : viewportHeight), - initialPos + offset - ), - position[side1], - - // Make sure we don't adjust complete off the element when using 'center' - mySide === 'center' ? initialPos - myLength : 1E9 - ) - ); - - } - - // flip/flipinvert - else { - // Update adjustment amount depending on if using flipinvert or flip - adjust *= (type === FLIPINVERT ? 2 : 0); - - // Check for overflow on the left/top - if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) { - position[side1] -= offset + adjust; - newMy.invert(side, side1); - } - - // Check for overflow on the bottom/right - else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) { - position[side1] -= (mySide === CENTER ? -offset : offset) + adjust; - newMy.invert(side, side2); - } - - // Make sure we haven't made things worse with the adjustment and reset if so - if(position[side1] < viewportScroll && -position[side1] > overflow2) { - position[side1] = initialPos; newMy = my.clone(); - } - } - - return position[side1] - initialPos; - } - - // Set newMy if using flip or flipinvert methods - if(methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone(); } - - // Adjust position based onviewport and adjustment options - adjusted = { - left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0, - top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0, - my: newMy - }; - - return adjusted; -}; -;PLUGINS.polys = { - // POLY area coordinate calculator - // Special thanks to Ed Cradock for helping out with this. - // Uses a binary search algorithm to find suitable coordinates. - polygon: function(baseCoords, corner) { - var result = { - width: 0, height: 0, - position: { - top: 1e10, right: 0, - bottom: 0, left: 1e10 - }, - adjustable: FALSE - }, - i = 0, next, - coords = [], - compareX = 1, compareY = 1, - realX = 0, realY = 0, - newWidth, newHeight; - - // First pass, sanitize coords and determine outer edges - i = baseCoords.length; while(i--) { - next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ]; - - if(next[0] > result.position.right){ result.position.right = next[0]; } - if(next[0] < result.position.left){ result.position.left = next[0]; } - if(next[1] > result.position.bottom){ result.position.bottom = next[1]; } - if(next[1] < result.position.top){ result.position.top = next[1]; } - - coords.push(next); - } - - // Calculate height and width from outer edges - newWidth = result.width = Math.abs(result.position.right - result.position.left); - newHeight = result.height = Math.abs(result.position.bottom - result.position.top); - - // If it's the center corner... - if(corner.abbrev() === 'c') { - result.position = { - left: result.position.left + (result.width / 2), - top: result.position.top + (result.height / 2) - }; - } - else { - // Second pass, use a binary search algorithm to locate most suitable coordinate - while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0) - { - newWidth = Math.floor(newWidth / 2); - newHeight = Math.floor(newHeight / 2); - - if(corner.x === LEFT){ compareX = newWidth; } - else if(corner.x === RIGHT){ compareX = result.width - newWidth; } - else{ compareX += Math.floor(newWidth / 2); } - - if(corner.y === TOP){ compareY = newHeight; } - else if(corner.y === BOTTOM){ compareY = result.height - newHeight; } - else{ compareY += Math.floor(newHeight / 2); } - - i = coords.length; while(i--) - { - if(coords.length < 2){ break; } - - realX = coords[i][0] - result.position.left; - realY = coords[i][1] - result.position.top; - - if((corner.x === LEFT && realX >= compareX) || - (corner.x === RIGHT && realX <= compareX) || - (corner.x === CENTER && (realX < compareX || realX > (result.width - compareX))) || - (corner.y === TOP && realY >= compareY) || - (corner.y === BOTTOM && realY <= compareY) || - (corner.y === CENTER && (realY < compareY || realY > (result.height - compareY)))) { - coords.splice(i, 1); - } - } - } - result.position = { left: coords[0][0], top: coords[0][1] }; - } - - return result; - }, - - rect: function(ax, ay, bx, by) { - return { - width: Math.abs(bx - ax), - height: Math.abs(by - ay), - position: { - left: Math.min(ax, bx), - top: Math.min(ay, by) - } - }; - }, - - _angles: { - tc: 3 / 2, tr: 7 / 4, tl: 5 / 4, - bc: 1 / 2, br: 1 / 4, bl: 3 / 4, - rc: 2, lc: 1, c: 0 - }, - ellipse: function(cx, cy, rx, ry, corner) { - var c = PLUGINS.polys._angles[ corner.abbrev() ], - rxc = c === 0 ? 0 : rx * Math.cos( c * Math.PI ), - rys = ry * Math.sin( c * Math.PI ); - - return { - width: (rx * 2) - Math.abs(rxc), - height: (ry * 2) - Math.abs(rys), - position: { - left: cx + rxc, - top: cy + rys - }, - adjustable: FALSE - }; - }, - circle: function(cx, cy, r, corner) { - return PLUGINS.polys.ellipse(cx, cy, r, r, corner); - } -}; -;PLUGINS.imagemap = function(api, area, corner, adjustMethod) -{ - if(!area.jquery) { area = $(area); } - - var shape = (area.attr('shape') || 'rect').toLowerCase().replace('poly', 'polygon'), - image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'), - coordsString = $.trim(area.attr('coords')), - coordsArray = coordsString.replace(/,$/, '').split(','), - imageOffset, coords, i, next, result, len; - - // If we can't find the image using the map... - if(!image.length) { return FALSE; } - - // Pass coordinates string if polygon - if(shape === 'polygon') { - result = PLUGINS.polys.polygon(coordsArray, corner); - } - - // Otherwise parse the coordinates and pass them as arguments - else if(PLUGINS.polys[shape]) { - for(i = -1, len = coordsArray.length, coords = []; ++i < len;) { - coords.push( parseInt(coordsArray[i], 10) ); - } - - result = PLUGINS.polys[shape].apply( - this, coords.concat(corner) - ); - } - - // If no shapre calculation method was found, return false - else { return FALSE; } - - // Make sure we account for padding and borders on the image - imageOffset = image.offset(); - imageOffset.left += Math.ceil((image.outerWidth(FALSE) - image.width()) / 2); - imageOffset.top += Math.ceil((image.outerHeight(FALSE) - image.height()) / 2); - - // Add image position to offset coordinates - result.position.left += imageOffset.left; - result.position.top += imageOffset.top; - - return result; -}; -;PLUGINS.svg = function(api, svg, corner) -{ - var doc = $(document), - elem = svg[0], - root = $(elem.ownerSVGElement), - ownerDocument = elem.ownerDocument, - strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2, - frameOffset, mtx, transformed, viewBox, - len, next, i, points, - result, position, dimensions; - - // Ascend the parentNode chain until we find an element with getBBox() - while(!elem.getBBox) { elem = elem.parentNode; } - if(!elem.getBBox || !elem.parentNode) { return FALSE; } - - // Determine which shape calculation to use - switch(elem.nodeName) { - case 'ellipse': - case 'circle': - result = PLUGINS.polys.ellipse( - elem.cx.baseVal.value, - elem.cy.baseVal.value, - (elem.rx || elem.r).baseVal.value + strokeWidth2, - (elem.ry || elem.r).baseVal.value + strokeWidth2, - corner - ); - break; - - case 'line': - case 'polygon': - case 'polyline': - // Determine points object (line has none, so mimic using array) - points = elem.points || [ - { x: elem.x1.baseVal.value, y: elem.y1.baseVal.value }, - { x: elem.x2.baseVal.value, y: elem.y2.baseVal.value } - ]; - - for(result = [], i = -1, len = points.numberOfItems || points.length; ++i < len;) { - next = points.getItem ? points.getItem(i) : points[i]; - result.push.apply(result, [next.x, next.y]); - } - - result = PLUGINS.polys.polygon(result, corner); - break; - - // Unknown shape or rectangle? Use bounding box - default: - result = elem.getBBox(); - result = { - width: result.width, - height: result.height, - position: { - left: result.x, - top: result.y - } - }; - break; - } - - // Shortcut assignments - position = result.position; - root = root[0]; - - // Convert position into a pixel value - if(root.createSVGPoint) { - mtx = elem.getScreenCTM(); - points = root.createSVGPoint(); - - points.x = position.left; - points.y = position.top; - transformed = points.matrixTransform( mtx ); - position.left = transformed.x; - position.top = transformed.y; - } - - // Check the element is not in a child document, and if so, adjust for frame elements offset - if(ownerDocument !== document && api.position.target !== 'mouse') { - frameOffset = $((ownerDocument.defaultView || ownerDocument.parentWindow).frameElement).offset(); - if(frameOffset) { - position.left += frameOffset.left; - position.top += frameOffset.top; - } - } - - // Adjust by scroll offset of owner document - ownerDocument = $(ownerDocument); - position.left += ownerDocument.scrollLeft(); - position.top += ownerDocument.scrollTop(); - - return result; -}; -;var MODAL, OVERLAY, - MODALCLASS = 'qtip-modal', - MODALSELECTOR = '.'+MODALCLASS; - -OVERLAY = function() -{ - var self = this, - focusableElems = {}, - current, onLast, - prevState, elem; - - // Modified code from jQuery UI 1.10.0 source - // http://code.jquery.com/ui/1.10.0/jquery-ui.js - function focusable(element) { - // Use the defined focusable checker when possible - if($.expr[':'].focusable) { return $.expr[':'].focusable; } - - var isTabIndexNotNaN = !isNaN($.attr(element, 'tabindex')), - nodeName = element.nodeName && element.nodeName.toLowerCase(), - map, mapName, img; - - if('area' === nodeName) { - map = element.parentNode; - mapName = map.name; - if(!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') { - return false; - } - img = $('img[usemap=#' + mapName + ']')[0]; - return !!img && img.is(':visible'); - } - return (/input|select|textarea|button|object/.test( nodeName ) ? - !element.disabled : - 'a' === nodeName ? - element.href || isTabIndexNotNaN : - isTabIndexNotNaN - ); - } - - // Focus inputs using cached focusable elements (see update()) - function focusInputs(blurElems) { - // Blurring body element in IE causes window.open windows to unfocus! - if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); } - - // Focus the inputs - else { focusableElems.first().focus(); } - } - - // Steal focus from elements outside tooltip - function stealFocus(event) { - if(!elem.is(':visible')) { return; } - - var target = $(event.target), - tooltip = current.tooltip, - container = target.closest(SELECTOR), - targetOnTop; - - // Determine if input container target is above this - targetOnTop = container.length < 1 ? FALSE : - (parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[0].style.zIndex, 10)); - - // If we're showing a modal, but focus has landed on an input below - // this modal, divert focus to the first visible input in this modal - // or if we can't find one... the tooltip itself - if(!targetOnTop && target.closest(SELECTOR)[0] !== tooltip[0]) { - focusInputs(target); - } - - // Detect when we leave the last focusable element... - onLast = event.target === focusableElems[focusableElems.length - 1]; - } - - $.extend(self, { - init: function() { - // Create document overlay - elem = self.elem = $('
', { - id: 'qtip-overlay', - html: '
', - mousedown: function() { return FALSE; } - }) - .hide(); - - // Make sure we can't focus anything outside the tooltip - $(document.body).bind('focusin'+MODALSELECTOR, stealFocus); - - // Apply keyboard "Escape key" close handler - $(document).bind('keydown'+MODALSELECTOR, function(event) { - if(current && current.options.show.modal.escape && event.keyCode === 27) { - current.hide(event); - } - }); - - // Apply click handler for blur option - elem.bind('click'+MODALSELECTOR, function(event) { - if(current && current.options.show.modal.blur) { - current.hide(event); - } - }); - - return self; - }, - - update: function(api) { - // Update current API reference - current = api; - - // Update focusable elements if enabled - if(api.options.show.modal.stealfocus !== FALSE) { - focusableElems = api.tooltip.find('*').filter(function() { - return focusable(this); - }); - } - else { focusableElems = []; } - }, - - toggle: function(api, state, duration) { - var docBody = $(document.body), - tooltip = api.tooltip, - options = api.options.show.modal, - effect = options.effect, - type = state ? 'show': 'hide', - visible = elem.is(':visible'), - visibleModals = $(MODALSELECTOR).filter(':visible:not(:animated)').not(tooltip), - zindex; - - // Set active tooltip API reference - self.update(api); - - // If the modal can steal the focus... - // Blur the current item and focus anything in the modal we an - if(state && options.stealfocus !== FALSE) { - focusInputs( $(':focus') ); - } - - // Toggle backdrop cursor style on show - elem.toggleClass('blurs', options.blur); - - // Append to body on show - if(state) { - elem.appendTo(document.body); - } - - // Prevent modal from conflicting with show.solo, and don't hide backdrop is other modals are visible - if((elem.is(':animated') && visible === state && prevState !== FALSE) || (!state && visibleModals.length)) { - return self; - } - - // Stop all animations - elem.stop(TRUE, FALSE); - - // Use custom function if provided - if($.isFunction(effect)) { - effect.call(elem, state); - } - - // If no effect type is supplied, use a simple toggle - else if(effect === FALSE) { - elem[ type ](); - } - - // Use basic fade function - else { - elem.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() { - if(!state) { elem.hide(); } - }); - } - - // Reset position and detach from body on hide - if(!state) { - elem.queue(function(next) { - elem.css({ left: '', top: '' }); - if(!$(MODALSELECTOR).length) { elem.detach(); } - next(); - }); - } - - // Cache the state - prevState = state; - - // If the tooltip is destroyed, set reference to null - if(current.destroyed) { current = NULL; } - - return self; - } - }); - - self.init(); -}; -OVERLAY = new OVERLAY(); - -function Modal(api, options) { - this.options = options; - this._ns = '-modal'; - - this.init( (this.qtip = api) ); -} - -$.extend(Modal.prototype, { - init: function(qtip) { - var tooltip = qtip.tooltip; - - // If modal is disabled... return - if(!this.options.on) { return this; } - - // Set overlay reference - qtip.elements.overlay = OVERLAY.elem; - - // Add unique attribute so we can grab modal tooltips easily via a SELECTOR, and set z-index - tooltip.addClass(MODALCLASS).css('z-index', QTIP.modal_zindex + $(MODALSELECTOR).length); - - // Apply our show/hide/focus modal events - qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function(event, api, duration) { - var oEvent = event.originalEvent; - - // Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop - if(event.target === tooltip[0]) { - if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(OVERLAY.elem[0]).length) { - try { event.preventDefault(); } catch(e) {} - } - else if(!oEvent || (oEvent && oEvent.type !== 'tooltipsolo')) { - this.toggle(event, event.type === 'tooltipshow', duration); - } - } - }, this._ns, this); - - // Adjust modal z-index on tooltip focus - qtip._bind(tooltip, 'tooltipfocus', function(event, api) { - // If focus was cancelled before it reached us, don't do anything - if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; } - - var qtips = $(MODALSELECTOR), - - // Keep the modal's lower than other, regular qtips - newIndex = QTIP.modal_zindex + qtips.length, - curIndex = parseInt(tooltip[0].style.zIndex, 10); - - // Set overlay z-index - OVERLAY.elem[0].style.zIndex = newIndex - 1; - - // Reduce modal z-index's and keep them properly ordered - qtips.each(function() { - if(this.style.zIndex > curIndex) { - this.style.zIndex -= 1; - } - }); - - // Fire blur event for focused tooltip - qtips.filter('.' + CLASS_FOCUS).qtip('blur', event.originalEvent); - - // Set the new z-index - tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; - - // Set current - OVERLAY.update(api); - - // Prevent default handling - try { event.preventDefault(); } catch(e) {} - }, this._ns, this); - - // Focus any other visible modals when this one hides - qtip._bind(tooltip, 'tooltiphide', function(event) { - if(event.target === tooltip[0]) { - $(MODALSELECTOR).filter(':visible').not(tooltip).last().qtip('focus', event); - } - }, this._ns, this); - }, - - toggle: function(event, state, duration) { - // Make sure default event hasn't been prevented - if(event && event.isDefaultPrevented()) { return this; } - - // Toggle it - OVERLAY.toggle(this.qtip, !!state, duration); - }, - - destroy: function() { - // Remove modal class - this.qtip.tooltip.removeClass(MODALCLASS); - - // Remove bound events - this.qtip._unbind(this.qtip.tooltip, this._ns); - - // Delete element reference - OVERLAY.toggle(this.qtip, FALSE); - delete this.qtip.elements.overlay; - } -}); - - -MODAL = PLUGINS.modal = function(api) { - return new Modal(api, api.options.show.modal); -}; - -// Setup sanitiztion rules -MODAL.sanitize = function(opts) { - if(opts.show) { - if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; } - else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; } - } -}; - -// Base z-index for all modal tooltips (use qTip core z-index as a base) -QTIP.modal_zindex = QTIP.zindex - 200; - -// Plugin needs to be initialized on render -MODAL.initialize = 'render'; - -// Setup option set checks -CHECKS.modal = { - '^show.modal.(on|blur)$': function() { - // Initialise - this.destroy(); - this.init(); - - // Show the modal if not visible already and tooltip is visible - this.qtip.elems.overlay.toggle( - this.qtip.tooltip[0].offsetWidth > 0 - ); - } -}; - -// Extend original api defaults -$.extend(TRUE, QTIP.defaults, { - show: { - modal: { - on: FALSE, - effect: TRUE, - blur: TRUE, - stealfocus: TRUE, - escape: TRUE - } - } -}); -;var IE6, - -/* - * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe) - * Special thanks to Brandon Aaron - */ -BGIFRAME = ''; - -function Ie6(api, qtip) { - this._ns = 'ie6'; - this.init( (this.qtip = api) ); -} - -$.extend(Ie6.prototype, { - _scroll : function() { - var overlay = this.qtip.elements.overlay; - overlay && (overlay[0].style.top = $(window).scrollTop() + 'px'); - }, - - init: function(qtip) { - var tooltip = qtip.tooltip, - scroll; - - // Create the BGIFrame element if needed - if($('select, object').length < 1) { - this.bgiframe = qtip.elements.bgiframe = $(BGIFRAME).appendTo(tooltip); - - // Update BGIFrame on tooltip move - qtip._bind(tooltip, 'tooltipmove', this.adjustBGIFrame, this._ns, this); - } - - // redraw() container for width/height calculations - this.redrawContainer = $('
', { id: NAMESPACE+'-rcontainer' }) - .appendTo(document.body); - - // Fixup modal plugin if present too - if( qtip.elements.overlay && qtip.elements.overlay.addClass('qtipmodal-ie6fix') ) { - qtip._bind(window, ['scroll', 'resize'], this._scroll, this._ns, this); - qtip._bind(tooltip, ['tooltipshow'], this._scroll, this._ns, this); - } - - // Set dimensions - this.redraw(); - }, - - adjustBGIFrame: function() { - var tooltip = this.qtip.tooltip, - dimensions = { - height: tooltip.outerHeight(FALSE), - width: tooltip.outerWidth(FALSE) - }, - plugin = this.qtip.plugins.tip, - tip = this.qtip.elements.tip, - tipAdjust, offset; - - // Adjust border offset - offset = parseInt(tooltip.css('borderLeftWidth'), 10) || 0; - offset = { left: -offset, top: -offset }; - - // Adjust for tips plugin - if(plugin && tip) { - tipAdjust = (plugin.corner.precedance === 'x') ? [WIDTH, LEFT] : [HEIGHT, TOP]; - offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ](); - } - - // Update bgiframe - this.bgiframe.css(offset).css(dimensions); - }, - - // Max/min width simulator function - redraw: function() { - if(this.qtip.rendered < 1 || this.drawing) { return this; } - - var tooltip = this.qtip.tooltip, - style = this.qtip.options.style, - container = this.qtip.options.position.container, - perc, width, max, min; - - // Set drawing flag - this.qtip.drawing = 1; - - // If tooltip has a set height/width, just set it... like a boss! - if(style.height) { tooltip.css(HEIGHT, style.height); } - if(style.width) { tooltip.css(WIDTH, style.width); } - - // Simulate max/min width if not set width present... - else { - // Reset width and add fluid class - tooltip.css(WIDTH, '').appendTo(this.redrawContainer); - - // Grab our tooltip width (add 1 if odd so we don't get wrapping problems.. huzzah!) - width = tooltip.width(); - if(width % 2 < 1) { width += 1; } - - // Grab our max/min properties - max = tooltip.css('maxWidth') || ''; - min = tooltip.css('minWidth') || ''; - - // Parse into proper pixel values - perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0; - max = ((max.indexOf('%') > -1 ? perc : 1) * parseInt(max, 10)) || width; - min = ((min.indexOf('%') > -1 ? perc : 1) * parseInt(min, 10)) || 0; - - // Determine new dimension size based on max/min/current values - width = max + min ? Math.min(Math.max(width, min), max) : width; - - // Set the newly calculated width and remvoe fluid class - tooltip.css(WIDTH, Math.round(width)).appendTo(container); - } - - // Set drawing flag - this.drawing = 0; - - return this; - }, - - destroy: function() { - // Remove iframe - this.bgiframe && this.bgiframe.remove(); - - // Remove bound events - this.qtip._unbind([window, this.qtip.tooltip], this._ns); - } -}); - -IE6 = PLUGINS.ie6 = function(api) { - // Proceed only if the browser is IE6 - return BROWSER.ie === 6 ? new Ie6(api) : FALSE; -}; - -IE6.initialize = 'render'; - -CHECKS.ie6 = { - '^content|style$': function() { - this.redraw(); - } -}; -;})); -}( window, document )); + +PROTOTYPE._assignInitialEvents = function(event) { + var options = this.options, + showTarget = options.show.target, + hideTarget = options.hide.target, + showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], + hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; + + // Catch remove/removeqtip events on target element to destroy redundant tooltips + this._bind(this.elements.target, ['remove', 'removeqtip'], function(event) { + this.destroy(true); + }, 'destroy'); + + /* + * Make sure hoverIntent functions properly by using mouseleave as a hide event if + * mouseenter/mouseout is used for show.event, even if it isn't in the users options. + */ + if(/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|leave)/i.test(options.hide.event)) { + hideEvents.push('mouseleave'); + } + + /* + * Also make sure initial mouse targetting works correctly by caching mousemove coords + * on show targets before the tooltip has rendered. Also set onTarget when triggered to + * keep mouse tracking working. + */ + this._bind(showTarget, 'mousemove', function(event) { + this._storeMouse(event); + this.cache.onTarget = TRUE; + }); + + // Define hoverIntent function + function hoverIntent(event) { + // Only continue if tooltip isn't disabled + if(this.disabled || this.destroyed) { return FALSE; } + + // Cache the event data + this.cache.event = event && $.event.fix(event); + this.cache.target = event && $(event.target); + + // Start the event sequence + clearTimeout(this.timers.show); + this.timers.show = delay.call(this, + function() { this.render(typeof event === 'object' || options.show.ready); }, + options.prerender ? 0 : options.show.delay + ); + } + + // Filter and bind events + this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() { + if(!this.timers) { return FALSE; } + clearTimeout(this.timers.show); + }); + + // Prerendering is enabled, create tooltip now + if(options.show.ready || options.prerender) { hoverIntent.call(this, event); } +}; + +// Event assignment method +PROTOTYPE._assignEvents = function() { + var self = this, + options = this.options, + posOptions = options.position, + + tooltip = this.tooltip, + showTarget = options.show.target, + hideTarget = options.hide.target, + containerTarget = posOptions.container, + viewportTarget = posOptions.viewport, + documentTarget = $(document), + bodyTarget = $(document.body), + windowTarget = $(window), + + showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], + hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; + + + // Assign passed event callbacks + $.each(options.events, function(name, callback) { + self._bind(tooltip, name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name], callback, null, tooltip); + }); + + // Hide tooltips when leaving current window/frame (but not select/option elements) + if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') { + this._bind(documentTarget, ['mouseout', 'blur'], function(event) { + if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { + this.hide(event); + } + }); + } + + // Enable hide.fixed by adding appropriate class + if(options.hide.fixed) { + hideTarget = hideTarget.add( tooltip.addClass(CLASS_FIXED) ); + } + + /* + * Make sure hoverIntent functions properly by using mouseleave to clear show timer if + * mouseenter/mouseout is used for show.event, even if it isn't in the users options. + */ + else if(/mouse(over|enter)/i.test(options.show.event)) { + this._bind(hideTarget, 'mouseleave', function() { + clearTimeout(this.timers.show); + }); + } + + // Hide tooltip on document mousedown if unfocus events are enabled + if(('' + options.hide.event).indexOf('unfocus') > -1) { + this._bind(containerTarget.closest('html'), ['mousedown', 'touchstart'], function(event) { + var elem = $(event.target), + enabled = this.rendered && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0, + isAncestor = elem.parents(SELECTOR).filter(this.tooltip[0]).length > 0; + + if(elem[0] !== this.target[0] && elem[0] !== this.tooltip[0] && !isAncestor && + !this.target.has(elem[0]).length && enabled + ) { + this.hide(event); + } + }); + } + + // Check if the tooltip hides when inactive + if('number' === typeof options.hide.inactive) { + // Bind inactive method to show target(s) as a custom event + this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod, 'inactive'); + + // Define events which reset the 'inactive' event handler + this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod); + } + + // Filter and bind events + this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod); + + // Mouse movement bindings + this._bind(showTarget.add(tooltip), 'mousemove', function(event) { + // Check if the tooltip hides when mouse is moved a certain distance + if('number' === typeof options.hide.distance) { + var origin = this.cache.origin || {}, + limit = this.options.hide.distance, + abs = Math.abs; + + // Check if the movement has gone beyond the limit, and hide it if so + if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) { + this.hide(event); + } + } + + // Cache mousemove coords on show targets + this._storeMouse(event); + }); + + // Mouse positioning events + if(posOptions.target === 'mouse') { + // If mouse adjustment is on... + if(posOptions.adjust.mouse) { + // Apply a mouseleave event so we don't get problems with overlapping + if(options.hide.event) { + // Track if we're on the target or not + this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) { + if(!this.cache) {return FALSE; } + this.cache.onTarget = event.type === 'mouseenter'; + }); + } + + // Update tooltip position on mousemove + this._bind(documentTarget, 'mousemove', function(event) { + // Update the tooltip position only if the tooltip is visible and adjustment is enabled + if(this.rendered && this.cache.onTarget && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) { + this.reposition(event); + } + }); + } + } + + // Adjust positions of the tooltip on window resize if enabled + if(posOptions.adjust.resize || viewportTarget.length) { + this._bind( $.event.special.resize ? viewportTarget : windowTarget, 'resize', repositionMethod ); + } + + // Adjust tooltip position on scroll of the window or viewport element if present + if(posOptions.adjust.scroll) { + this._bind( windowTarget.add(posOptions.container), 'scroll', repositionMethod ); + } +}; + +// Un-assignment method +PROTOTYPE._unassignEvents = function() { + var options = this.options, + showTargets = options.show.target, + hideTargets = options.hide.target, + targets = $.grep([ + this.elements.target[0], + this.rendered && this.tooltip[0], + options.position.container[0], + options.position.viewport[0], + options.position.container.closest('html')[0], // unfocus + window, + document + ], function(i) { + return typeof i === 'object'; + }); + + // Add show and hide targets if they're valid + if(showTargets && showTargets.toArray) { + targets = targets.concat(showTargets.toArray()); + } + if(hideTargets && hideTargets.toArray) { + targets = targets.concat(hideTargets.toArray()); + } + + // Unbind the events + this._unbind(targets) + ._unbind(targets, 'destroy') + ._unbind(targets, 'inactive'); +}; + +// Apply common event handlers using delegate (avoids excessive .bind calls!) +$(function() { + delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) { + var state = event.type === 'mouseenter', + tooltip = $(event.currentTarget), + target = $(event.relatedTarget || event.target), + options = this.options; + + // On mouseenter... + if(state) { + // Focus the tooltip on mouseenter (z-index stacking) + this.focus(event); + + // Clear hide timer on tooltip hover to prevent it from closing + tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide); + } + + // On mouseleave... + else { + // When mouse tracking is enabled, hide when we leave the tooltip and not onto the show target (if a hide event is set) + if(options.position.target === 'mouse' && options.position.adjust.mouse && + options.hide.event && options.show.target && !target.closest(options.show.target[0]).length) { + this.hide(event); + } + } + + // Add hover class + tooltip.toggleClass(CLASS_HOVER, state); + }); + + // Define events which reset the 'inactive' event handler + delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod); +}); +;// Initialization method +function init(elem, id, opts) { + var obj, posOptions, attr, config, title, + + // Setup element references + docBody = $(document.body), + + // Use document body instead of document element if needed + newTarget = elem[0] === document ? docBody : elem, + + // Grab metadata from element if plugin is present + metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL, + + // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise + metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL, + + // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method, + html5 = elem.data(opts.metadata.name || 'qtipopts'); + + // If we don't get an object returned attempt to parse it manualyl without parseJSON + try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {} + + // Merge in and sanitize metadata + config = $.extend(TRUE, {}, QTIP.defaults, opts, + typeof html5 === 'object' ? sanitizeOptions(html5) : NULL, + sanitizeOptions(metadata5 || metadata)); + + // Re-grab our positioning options now we've merged our metadata and set id to passed value + posOptions = config.position; + config.id = id; + + // Setup missing content if none is detected + if('boolean' === typeof config.content.text) { + attr = elem.attr(config.content.attr); + + // Grab from supplied attribute if available + if(config.content.attr !== FALSE && attr) { config.content.text = attr; } + + // No valid content was found, abort render + else { return FALSE; } + } + + // Setup target options + if(!posOptions.container.length) { posOptions.container = docBody; } + if(posOptions.target === FALSE) { posOptions.target = newTarget; } + if(config.show.target === FALSE) { config.show.target = newTarget; } + if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); } + if(config.hide.target === FALSE) { config.hide.target = newTarget; } + if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; } + + // Ensure we only use a single container + posOptions.container = posOptions.container.eq(0); + + // Convert position corner values into x and y strings + posOptions.at = new CORNER(posOptions.at, TRUE); + posOptions.my = new CORNER(posOptions.my); + + // Destroy previous tooltip if overwrite is enabled, or skip element if not + if(elem.data(NAMESPACE)) { + if(config.overwrite) { + elem.qtip('destroy', true); + } + else if(config.overwrite === FALSE) { + return FALSE; + } + } + + // Add has-qtip attribute + elem.attr(ATTR_HAS, id); + + // Remove title attribute and store it if present + if(config.suppress && (title = elem.attr('title'))) { + // Final attr call fixes event delegatiom and IE default tooltip showing problem + elem.removeAttr('title').attr(oldtitle, title).attr('title', ''); + } + + // Initialize the tooltip and add API reference + obj = new QTip(elem, config, id, !!attr); + elem.data(NAMESPACE, obj); + + return obj; +} + +// jQuery $.fn extension method +QTIP = $.fn.qtip = function(options, notation, newValue) +{ + var command = ('' + options).toLowerCase(), // Parse command + returned = NULL, + args = $.makeArray(arguments).slice(1), + event = args[args.length - 1], + opts = this[0] ? $.data(this[0], NAMESPACE) : NULL; + + // Check for API request + if((!arguments.length && opts) || command === 'api') { + return opts; + } + + // Execute API command if present + else if('string' === typeof options) { + this.each(function() { + var api = $.data(this, NAMESPACE); + if(!api) { return TRUE; } + + // Cache the event if possible + if(event && event.timeStamp) { api.cache.event = event; } + + // Check for specific API commands + if(notation && (command === 'option' || command === 'options')) { + if(newValue !== undefined || $.isPlainObject(notation)) { + api.set(notation, newValue); + } + else { + returned = api.get(notation); + return FALSE; + } + } + + // Execute API command + else if(api[command]) { + api[command].apply(api, args); + } + }); + + return returned !== NULL ? returned : this; + } + + // No API commands. validate provided options and setup qTips + else if('object' === typeof options || !arguments.length) { + // Sanitize options first + opts = sanitizeOptions($.extend(TRUE, {}, options)); + + return this.each(function(i) { + var api, id; + + // Find next available ID, or use custom ID if provided + id = $.isArray(opts.id) ? opts.id[i] : opts.id; + id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id; + + // Initialize the qTip and re-grab newly sanitized options + api = init($(this), id, opts); + if(api === FALSE) { return TRUE; } + else { QTIP.api[id] = api; } + + // Initialize plugins + $.each(PLUGINS, function() { + if(this.initialize === 'initialize') { this(api); } + }); + + // Assign initial pre-render events + api._assignInitialEvents(event); + }); + } +}; + +// Expose class +$.qtip = QTip; + +// Populated in render method +QTIP.api = {}; +;$.each({ + /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */ + attr: function(attr, val) { + if(this.length) { + var self = this[0], + title = 'title', + api = $.data(self, 'qtip'); + + if(attr === title && api && 'object' === typeof api && api.options.suppress) { + if(arguments.length < 2) { + return $.attr(self, oldtitle); + } + + // If qTip is rendered and title was originally used as content, update it + if(api && api.options.content.attr === title && api.cache.attr) { + api.set('content.text', val); + } + + // Use the regular attr method to set, then cache the result + return this.attr(oldtitle, val); + } + } + + return $.fn['attr'+replaceSuffix].apply(this, arguments); + }, + + /* Allow clone to correctly retrieve cached title attributes */ + clone: function(keepData) { + var titles = $([]), title = 'title', + + // Clone our element using the real clone method + elems = $.fn['clone'+replaceSuffix].apply(this, arguments); + + // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false + if(!keepData) { + elems.filter('['+oldtitle+']').attr('title', function() { + return $.attr(this, oldtitle); + }) + .removeAttr(oldtitle); + } + + return elems; + } +}, function(name, func) { + if(!func || $.fn[name+replaceSuffix]) { return TRUE; } + + var old = $.fn[name+replaceSuffix] = $.fn[name]; + $.fn[name] = function() { + return func.apply(this, arguments) || old.apply(this, arguments); + }; +}); + +/* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar). + * This snippet is taken directly from jQuery UI source code found here: + * http://code.jquery.com/ui/jquery-ui-git.js + */ +if(!$.ui) { + $['cleanData'+replaceSuffix] = $.cleanData; + $.cleanData = function( elems ) { + for(var i = 0, elem; (elem = $( elems[i] )).length; i++) { + if(elem.attr(ATTR_HAS)) { + try { elem.triggerHandler('removeqtip'); } + catch( e ) {} + } + } + $['cleanData'+replaceSuffix].apply(this, arguments); + }; +} +;// qTip version +QTIP.version = '2.2.1'; + +// Base ID for all qTips +QTIP.nextid = 0; + +// Inactive events array +QTIP.inactiveEvents = INACTIVE_EVENTS; + +// Base z-index for all qTips +QTIP.zindex = 15000; + +// Define configuration defaults +QTIP.defaults = { + prerender: FALSE, + id: FALSE, + overwrite: TRUE, + suppress: TRUE, + content: { + text: TRUE, + attr: 'title', + title: FALSE, + button: FALSE + }, + position: { + my: 'top left', + at: 'bottom right', + target: FALSE, + container: FALSE, + viewport: FALSE, + adjust: { + x: 0, y: 0, + mouse: TRUE, + scroll: TRUE, + resize: TRUE, + method: 'flipinvert flipinvert' + }, + effect: function(api, pos, viewport) { + $(this).animate(pos, { + duration: 200, + queue: FALSE + }); + } + }, + show: { + target: FALSE, + event: 'mouseenter', + effect: TRUE, + delay: 90, + solo: FALSE, + ready: FALSE, + autofocus: FALSE + }, + hide: { + target: FALSE, + event: 'mouseleave', + effect: TRUE, + delay: 0, + fixed: FALSE, + inactive: FALSE, + leave: 'window', + distance: FALSE + }, + style: { + classes: '', + widget: FALSE, + width: FALSE, + height: FALSE, + def: TRUE + }, + events: { + render: NULL, + move: NULL, + show: NULL, + hide: NULL, + toggle: NULL, + visible: NULL, + hidden: NULL, + focus: NULL, + blur: NULL + } +}; +;var TIP, + +// .bind()/.on() namespace +TIPNS = '.qtip-tip', + +// Common CSS strings +MARGIN = 'margin', +BORDER = 'border', +COLOR = 'color', +BG_COLOR = 'background-color', +TRANSPARENT = 'transparent', +IMPORTANT = ' !important', + +// Check if the browser supports elements +HASCANVAS = !!document.createElement('canvas').getContext, + +// Invalid colour values used in parseColours() +INVALID = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i; + +// Camel-case method, taken from jQuery source +// http://code.jquery.com/jquery-1.8.0.js +function camel(s) { return s.charAt(0).toUpperCase() + s.slice(1); } + +/* + * Modified from Modernizr's testPropsAll() + * http://modernizr.com/downloads/modernizr-latest.js + */ +var cssProps = {}, cssPrefixes = ["Webkit", "O", "Moz", "ms"]; +function vendorCss(elem, prop) { + var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), + props = (prop + ' ' + cssPrefixes.join(ucProp + ' ') + ucProp).split(' '), + cur, val, i = 0; + + // If the property has already been mapped... + if(cssProps[prop]) { return elem.css(cssProps[prop]); } + + while((cur = props[i++])) { + if((val = elem.css(cur)) !== undefined) { + return cssProps[prop] = cur, val; + } + } +} + +// Parse a given elements CSS property into an int +function intCss(elem, prop) { + return Math.ceil(parseFloat(vendorCss(elem, prop))); +} + + +// VML creation (for IE only) +if(!HASCANVAS) { + var createVML = function(tag, props, style) { + return ''; + }; +} + +// Canvas only definitions +else { + var PIXEL_RATIO = window.devicePixelRatio || 1, + BACKING_STORE_RATIO = (function() { + var context = document.createElement('canvas').getContext('2d'); + return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || 1; + }()), + SCALE = PIXEL_RATIO / BACKING_STORE_RATIO; +} + + +function Tip(qtip, options) { + this._ns = 'tip'; + this.options = options; + this.offset = options.offset; + this.size = [ options.width, options.height ]; + + // Initialize + this.init( (this.qtip = qtip) ); +} + +$.extend(Tip.prototype, { + init: function(qtip) { + var context, tip; + + // Create tip element and prepend to the tooltip + tip = this.element = qtip.elements.tip = $('
', { 'class': NAMESPACE+'-tip' }).prependTo(qtip.tooltip); + + // Create tip drawing element(s) + if(HASCANVAS) { + // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()! + context = $('').appendTo(this.element)[0].getContext('2d'); + + // Setup constant parameters + context.lineJoin = 'miter'; + context.miterLimit = 100000; + context.save(); + } + else { + context = createVML('shape', 'coordorigin="0,0"', 'position:absolute;'); + this.element.html(context + context); + + // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML + qtip._bind( $('*', tip).add(tip), ['click', 'mousedown'], function(event) { event.stopPropagation(); }, this._ns); + } + + // Bind update events + qtip._bind(qtip.tooltip, 'tooltipmove', this.reposition, this._ns, this); + + // Create it + this.create(); + }, + + _swapDimensions: function() { + this.size[0] = this.options.height; + this.size[1] = this.options.width; + }, + _resetDimensions: function() { + this.size[0] = this.options.width; + this.size[1] = this.options.height; + }, + + _useTitle: function(corner) { + var titlebar = this.qtip.elements.titlebar; + return titlebar && ( + corner.y === TOP || (corner.y === CENTER && this.element.position().top + (this.size[1] / 2) + this.options.offset < titlebar.outerHeight(TRUE)) + ); + }, + + _parseCorner: function(corner) { + var my = this.qtip.options.position.my; + + // Detect corner and mimic properties + if(corner === FALSE || my === FALSE) { + corner = FALSE; + } + else if(corner === TRUE) { + corner = new CORNER( my.string() ); + } + else if(!corner.string) { + corner = new CORNER(corner); + corner.fixed = TRUE; + } + + return corner; + }, + + _parseWidth: function(corner, side, use) { + var elements = this.qtip.elements, + prop = BORDER + camel(side) + 'Width'; + + return (use ? intCss(use, prop) : ( + intCss(elements.content, prop) || + intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || + intCss(elements.tooltip, prop) + )) || 0; + }, + + _parseRadius: function(corner) { + var elements = this.qtip.elements, + prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius'; + + return BROWSER.ie < 9 ? 0 : + intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || + intCss(elements.tooltip, prop) || 0; + }, + + _invalidColour: function(elem, prop, compare) { + var val = elem.css(prop); + return !val || (compare && val === elem.css(compare)) || INVALID.test(val) ? FALSE : val; + }, + + _parseColours: function(corner) { + var elements = this.qtip.elements, + tip = this.element.css('cssText', ''), + borderSide = BORDER + camel(corner[ corner.precedance ]) + camel(COLOR), + colorElem = this._useTitle(corner) && elements.titlebar || elements.content, + css = this._invalidColour, color = []; + + // Attempt to detect the background colour from various elements, left-to-right precedance + color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) || + css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR); + + // Attempt to detect the correct border side colour from various elements, left-to-right precedance + color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) || + css(elements.content, borderSide, COLOR) || css(elements.tooltip, borderSide, COLOR) || elements.tooltip.css(borderSide); + + // Reset background and border colours + $('*', tip).add(tip).css('cssText', BG_COLOR+':'+TRANSPARENT+IMPORTANT+';'+BORDER+':0'+IMPORTANT+';'); + + return color; + }, + + _calculateSize: function(corner) { + var y = corner.precedance === Y, + width = this.options['width'], + height = this.options['height'], + isCenter = corner.abbrev() === 'c', + base = (y ? width: height) * (isCenter ? 0.5 : 1), + pow = Math.pow, + round = Math.round, + bigHyp, ratio, result, + + smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ), + hyp = [ (this.border / base) * smallHyp, (this.border / height) * smallHyp ]; + + hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(this.border, 2) ); + hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(this.border, 2) ); + + bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]); + ratio = bigHyp / smallHyp; + + result = [ round(ratio * width), round(ratio * height) ]; + return y ? result : result.reverse(); + }, + + // Tip coordinates calculator + _calculateTip: function(corner, size, scale) { + scale = scale || 1; + size = size || this.size; + + var width = size[0] * scale, + height = size[1] * scale, + width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2), + + // Define tip coordinates in terms of height and width values + tips = { + br: [0,0, width,height, width,0], + bl: [0,0, width,0, 0,height], + tr: [0,height, width,0, width,height], + tl: [0,0, 0,height, width,height], + tc: [0,height, width2,0, width,height], + bc: [0,0, width,0, width2,height], + rc: [0,0, width,height2, 0,height], + lc: [width,0, width,height, 0,height2] + }; + + // Set common side shapes + tips.lt = tips.br; tips.rt = tips.bl; + tips.lb = tips.tr; tips.rb = tips.tl; + + return tips[ corner.abbrev() ]; + }, + + // Tip coordinates drawer (canvas) + _drawCoords: function(context, coords) { + context.beginPath(); + context.moveTo(coords[0], coords[1]); + context.lineTo(coords[2], coords[3]); + context.lineTo(coords[4], coords[5]); + context.closePath(); + }, + + create: function() { + // Determine tip corner + var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner); + + // If we have a tip corner... + if( (this.enabled = !!this.corner && this.corner.abbrev() !== 'c') ) { + // Cache it + this.qtip.cache.corner = c.clone(); + + // Create it + this.update(); + } + + // Toggle tip element + this.element.toggle(this.enabled); + + return this.corner; + }, + + update: function(corner, position) { + if(!this.enabled) { return this; } + + var elements = this.qtip.elements, + tip = this.element, + inner = tip.children(), + options = this.options, + curSize = this.size, + mimic = options.mimic, + round = Math.round, + color, precedance, context, + coords, bigCoords, translate, newSize, border, BACKING_STORE_RATIO; + + // Re-determine tip if not already set + if(!corner) { corner = this.qtip.cache.corner || this.corner; } + + // Use corner property if we detect an invalid mimic value + if(mimic === FALSE) { mimic = corner; } + + // Otherwise inherit mimic properties from the corner object as necessary + else { + mimic = new CORNER(mimic); + mimic.precedance = corner.precedance; + + if(mimic.x === 'inherit') { mimic.x = corner.x; } + else if(mimic.y === 'inherit') { mimic.y = corner.y; } + else if(mimic.x === mimic.y) { + mimic[ corner.precedance ] = corner[ corner.precedance ]; + } + } + precedance = mimic.precedance; + + // Ensure the tip width.height are relative to the tip position + if(corner.precedance === X) { this._swapDimensions(); } + else { this._resetDimensions(); } + + // Update our colours + color = this.color = this._parseColours(corner); + + // Detect border width, taking into account colours + if(color[1] !== TRANSPARENT) { + // Grab border width + border = this.border = this._parseWidth(corner, corner[corner.precedance]); + + // If border width isn't zero, use border color as fill if it's not invalid (1.0 style tips) + if(options.border && border < 1 && !INVALID.test(color[1])) { color[0] = color[1]; } + + // Set border width (use detected border width if options.border is true) + this.border = border = options.border !== TRUE ? options.border : border; + } + + // Border colour was invalid, set border to zero + else { this.border = border = 0; } + + // Determine tip size + newSize = this.size = this._calculateSize(corner); + tip.css({ + width: newSize[0], + height: newSize[1], + lineHeight: newSize[1]+'px' + }); + + // Calculate tip translation + if(corner.precedance === Y) { + translate = [ + round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] - curSize[0] - border : (newSize[0] - curSize[0]) / 2), + round(mimic.y === TOP ? newSize[1] - curSize[1] : 0) + ]; + } + else { + translate = [ + round(mimic.x === LEFT ? newSize[0] - curSize[0] : 0), + round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] - curSize[1] - border : (newSize[1] - curSize[1]) / 2) + ]; + } + + // Canvas drawing implementation + if(HASCANVAS) { + // Grab canvas context and clear/save it + context = inner[0].getContext('2d'); + context.restore(); context.save(); + context.clearRect(0,0,6000,6000); + + // Calculate coordinates + coords = this._calculateTip(mimic, curSize, SCALE); + bigCoords = this._calculateTip(mimic, this.size, SCALE); + + // Set the canvas size using calculated size + inner.attr(WIDTH, newSize[0] * SCALE).attr(HEIGHT, newSize[1] * SCALE); + inner.css(WIDTH, newSize[0]).css(HEIGHT, newSize[1]); + + // Draw the outer-stroke tip + this._drawCoords(context, bigCoords); + context.fillStyle = color[1]; + context.fill(); + + // Draw the actual tip + context.translate(translate[0] * SCALE, translate[1] * SCALE); + this._drawCoords(context, coords); + context.fillStyle = color[0]; + context.fill(); + } + + // VML (IE Proprietary implementation) + else { + // Calculate coordinates + coords = this._calculateTip(mimic); + + // Setup coordinates string + coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2] + + ',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + ' xe'; + + // Setup VML-specific offset for pixel-perfection + translate[2] = border && /^(r|b)/i.test(corner.string()) ? + BROWSER.ie === 8 ? 2 : 1 : 0; + + // Set initial CSS + inner.css({ + coordsize: (newSize[0]+border) + ' ' + (newSize[1]+border), + antialias: ''+(mimic.string().indexOf(CENTER) > -1), + left: translate[0] - (translate[2] * Number(precedance === X)), + top: translate[1] - (translate[2] * Number(precedance === Y)), + width: newSize[0] + border, + height: newSize[1] + border + }) + .each(function(i) { + var $this = $(this); + + // Set shape specific attributes + $this[ $this.prop ? 'prop' : 'attr' ]({ + coordsize: (newSize[0]+border) + ' ' + (newSize[1]+border), + path: coords, + fillcolor: color[0], + filled: !!i, + stroked: !i + }) + .toggle(!!(border || i)); + + // Check if border is enabled and add stroke element + !i && $this.html( createVML( + 'stroke', 'weight="'+(border*2)+'px" color="'+color[1]+'" miterlimit="1000" joinstyle="miter"' + ) ); + }); + } + + // Opera bug #357 - Incorrect tip position + // https://github.com/Craga89/qTip2/issues/367 + window.opera && setTimeout(function() { + elements.tip.css({ + display: 'inline-block', + visibility: 'visible' + }); + }, 1); + + // Position if needed + if(position !== FALSE) { this.calculate(corner, newSize); } + }, + + calculate: function(corner, size) { + if(!this.enabled) { return FALSE; } + + var self = this, + elements = this.qtip.elements, + tip = this.element, + userOffset = this.options.offset, + isWidget = elements.tooltip.hasClass('ui-widget'), + position = { }, + precedance, corners; + + // Inherit corner if not provided + corner = corner || this.corner; + precedance = corner.precedance; + + // Determine which tip dimension to use for adjustment + size = size || this._calculateSize(corner); + + // Setup corners and offset array + corners = [ corner.x, corner.y ]; + if(precedance === X) { corners.reverse(); } + + // Calculate tip position + $.each(corners, function(i, side) { + var b, bc, br; + + if(side === CENTER) { + b = precedance === Y ? LEFT : TOP; + position[ b ] = '50%'; + position[MARGIN+'-' + b] = -Math.round(size[ precedance === Y ? 0 : 1 ] / 2) + userOffset; + } + else { + b = self._parseWidth(corner, side, elements.tooltip); + bc = self._parseWidth(corner, side, elements.content); + br = self._parseRadius(corner); + + position[ side ] = Math.max(-self.border, i ? bc : (userOffset + (br > b ? br : -b))); + } + }); + + // Adjust for tip size + position[ corner[precedance] ] -= size[ precedance === X ? 0 : 1 ]; + + // Set and return new position + tip.css({ margin: '', top: '', bottom: '', left: '', right: '' }).css(position); + return position; + }, + + reposition: function(event, api, pos, viewport) { + if(!this.enabled) { return; } + + var cache = api.cache, + newCorner = this.corner.clone(), + adjust = pos.adjusted, + method = api.options.position.adjust.method.split(' '), + horizontal = method[0], + vertical = method[1] || method[0], + shift = { left: FALSE, top: FALSE, x: 0, y: 0 }, + offset, css = {}, props; + + function shiftflip(direction, precedance, popposite, side, opposite) { + // Horizontal - Shift or flip method + if(direction === SHIFT && newCorner.precedance === precedance && adjust[side] && newCorner[popposite] !== CENTER) { + newCorner.precedance = newCorner.precedance === X ? Y : X; + } + else if(direction !== SHIFT && adjust[side]){ + newCorner[precedance] = newCorner[precedance] === CENTER ? + (adjust[side] > 0 ? side : opposite) : (newCorner[precedance] === side ? opposite : side); + } + } + + function shiftonly(xy, side, opposite) { + if(newCorner[xy] === CENTER) { + css[MARGIN+'-'+side] = shift[xy] = offset[MARGIN+'-'+side] - adjust[side]; + } + else { + props = offset[opposite] !== undefined ? + [ adjust[side], -offset[side] ] : [ -adjust[side], offset[side] ]; + + if( (shift[xy] = Math.max(props[0], props[1])) > props[0] ) { + pos[side] -= adjust[side]; + shift[side] = FALSE; + } + + css[ offset[opposite] !== undefined ? opposite : side ] = shift[xy]; + } + } + + // If our tip position isn't fixed e.g. doesn't adjust with viewport... + if(this.corner.fixed !== TRUE) { + // Perform shift/flip adjustments + shiftflip(horizontal, X, Y, LEFT, RIGHT); + shiftflip(vertical, Y, X, TOP, BOTTOM); + + // Update and redraw the tip if needed (check cached details of last drawn tip) + if(newCorner.string() !== cache.corner.string() || cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left) { + this.update(newCorner, FALSE); + } + } + + // Setup tip offset properties + offset = this.calculate(newCorner); + + // Readjust offset object to make it left/top + if(offset.right !== undefined) { offset.left = -offset.right; } + if(offset.bottom !== undefined) { offset.top = -offset.bottom; } + offset.user = this.offset; + + // Perform shift adjustments + if(shift.left = (horizontal === SHIFT && !!adjust.left)) { shiftonly(X, LEFT, RIGHT); } + if(shift.top = (vertical === SHIFT && !!adjust.top)) { shiftonly(Y, TOP, BOTTOM); } + + /* + * If the tip is adjusted in both dimensions, or in a + * direction that would cause it to be anywhere but the + * outer border, hide it! + */ + this.element.css(css).toggle( + !((shift.x && shift.y) || (newCorner.x === CENTER && shift.y) || (newCorner.y === CENTER && shift.x)) + ); + + // Adjust position to accomodate tip dimensions + pos.left -= offset.left.charAt ? offset.user : + horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left + this.border : 0; + pos.top -= offset.top.charAt ? offset.user : + vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top + this.border : 0; + + // Cache details + cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top; + cache.corner = newCorner.clone(); + }, + + destroy: function() { + // Unbind events + this.qtip._unbind(this.qtip.tooltip, this._ns); + + // Remove the tip element(s) + if(this.qtip.elements.tip) { + this.qtip.elements.tip.find('*') + .remove().end().remove(); + } + } +}); + +TIP = PLUGINS.tip = function(api) { + return new Tip(api, api.options.style.tip); +}; + +// Initialize tip on render +TIP.initialize = 'render'; + +// Setup plugin sanitization options +TIP.sanitize = function(options) { + if(options.style && 'tip' in options.style) { + var opts = options.style.tip; + if(typeof opts !== 'object') { opts = options.style.tip = { corner: opts }; } + if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; } + } +}; + +// Add new option checks for the plugin +CHECKS.tip = { + '^position.my|style.tip.(corner|mimic|border)$': function() { + // Make sure a tip can be drawn + this.create(); + + // Reposition the tooltip + this.qtip.reposition(); + }, + '^style.tip.(height|width)$': function(obj) { + // Re-set dimensions and redraw the tip + this.size = [ obj.width, obj.height ]; + this.update(); + + // Reposition the tooltip + this.qtip.reposition(); + }, + '^content.title|style.(classes|widget)$': function() { + this.update(); + } +}; + +// Extend original qTip defaults +$.extend(TRUE, QTIP.defaults, { + style: { + tip: { + corner: TRUE, + mimic: FALSE, + width: 6, + height: 6, + border: TRUE, + offset: 0 + } + } +}); +;PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight) +{ + var target = posOptions.target, + tooltip = api.elements.tooltip, + my = posOptions.my, + at = posOptions.at, + adjust = posOptions.adjust, + method = adjust.method.split(' '), + methodX = method[0], + methodY = method[1] || method[0], + viewport = posOptions.viewport, + container = posOptions.container, + cache = api.cache, + adjusted = { left: 0, top: 0 }, + fixed, newMy, containerOffset, containerStatic, + viewportWidth, viewportHeight, viewportScroll, viewportOffset; + + // If viewport is not a jQuery element, or it's the window/document, or no adjustment method is used... return + if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') { + return adjusted; + } + + // Cach container details + containerOffset = container.offset() || adjusted; + containerStatic = container.css('position') === 'static'; + + // Cache our viewport details + fixed = tooltip.css('position') === 'fixed'; + viewportWidth = viewport[0] === window ? viewport.width() : viewport.outerWidth(FALSE); + viewportHeight = viewport[0] === window ? viewport.height() : viewport.outerHeight(FALSE); + viewportScroll = { left: fixed ? 0 : viewport.scrollLeft(), top: fixed ? 0 : viewport.scrollTop() }; + viewportOffset = viewport.offset() || adjusted; + + // Generic calculation method + function calculate(side, otherSide, type, adjust, side1, side2, lengthName, targetLength, elemLength) { + var initialPos = position[side1], + mySide = my[side], + atSide = at[side], + isShift = type === SHIFT, + myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2, + atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2, + sideOffset = viewportScroll[side1] + viewportOffset[side1] - (containerStatic ? 0 : containerOffset[side1]), + overflow1 = sideOffset - initialPos, + overflow2 = initialPos + elemLength - (lengthName === WIDTH ? viewportWidth : viewportHeight) - sideOffset, + offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0); + + // shift + if(isShift) { + offset = (mySide === side1 ? 1 : -1) * myLength; + + // Adjust position but keep it within viewport dimensions + position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0; + position[side1] = Math.max( + -containerOffset[side1] + viewportOffset[side1], + initialPos - offset, + Math.min( + Math.max( + -containerOffset[side1] + viewportOffset[side1] + (lengthName === WIDTH ? viewportWidth : viewportHeight), + initialPos + offset + ), + position[side1], + + // Make sure we don't adjust complete off the element when using 'center' + mySide === 'center' ? initialPos - myLength : 1E9 + ) + ); + + } + + // flip/flipinvert + else { + // Update adjustment amount depending on if using flipinvert or flip + adjust *= (type === FLIPINVERT ? 2 : 0); + + // Check for overflow on the left/top + if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) { + position[side1] -= offset + adjust; + newMy.invert(side, side1); + } + + // Check for overflow on the bottom/right + else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) { + position[side1] -= (mySide === CENTER ? -offset : offset) + adjust; + newMy.invert(side, side2); + } + + // Make sure we haven't made things worse with the adjustment and reset if so + if(position[side1] < viewportScroll && -position[side1] > overflow2) { + position[side1] = initialPos; newMy = my.clone(); + } + } + + return position[side1] - initialPos; + } + + // Set newMy if using flip or flipinvert methods + if(methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone(); } + + // Adjust position based onviewport and adjustment options + adjusted = { + left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0, + top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0, + my: newMy + }; + + return adjusted; +}; +;PLUGINS.polys = { + // POLY area coordinate calculator + // Special thanks to Ed Cradock for helping out with this. + // Uses a binary search algorithm to find suitable coordinates. + polygon: function(baseCoords, corner) { + var result = { + width: 0, height: 0, + position: { + top: 1e10, right: 0, + bottom: 0, left: 1e10 + }, + adjustable: FALSE + }, + i = 0, next, + coords = [], + compareX = 1, compareY = 1, + realX = 0, realY = 0, + newWidth, newHeight; + + // First pass, sanitize coords and determine outer edges + i = baseCoords.length; while(i--) { + next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ]; + + if(next[0] > result.position.right){ result.position.right = next[0]; } + if(next[0] < result.position.left){ result.position.left = next[0]; } + if(next[1] > result.position.bottom){ result.position.bottom = next[1]; } + if(next[1] < result.position.top){ result.position.top = next[1]; } + + coords.push(next); + } + + // Calculate height and width from outer edges + newWidth = result.width = Math.abs(result.position.right - result.position.left); + newHeight = result.height = Math.abs(result.position.bottom - result.position.top); + + // If it's the center corner... + if(corner.abbrev() === 'c') { + result.position = { + left: result.position.left + (result.width / 2), + top: result.position.top + (result.height / 2) + }; + } + else { + // Second pass, use a binary search algorithm to locate most suitable coordinate + while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0) + { + newWidth = Math.floor(newWidth / 2); + newHeight = Math.floor(newHeight / 2); + + if(corner.x === LEFT){ compareX = newWidth; } + else if(corner.x === RIGHT){ compareX = result.width - newWidth; } + else{ compareX += Math.floor(newWidth / 2); } + + if(corner.y === TOP){ compareY = newHeight; } + else if(corner.y === BOTTOM){ compareY = result.height - newHeight; } + else{ compareY += Math.floor(newHeight / 2); } + + i = coords.length; while(i--) + { + if(coords.length < 2){ break; } + + realX = coords[i][0] - result.position.left; + realY = coords[i][1] - result.position.top; + + if((corner.x === LEFT && realX >= compareX) || + (corner.x === RIGHT && realX <= compareX) || + (corner.x === CENTER && (realX < compareX || realX > (result.width - compareX))) || + (corner.y === TOP && realY >= compareY) || + (corner.y === BOTTOM && realY <= compareY) || + (corner.y === CENTER && (realY < compareY || realY > (result.height - compareY)))) { + coords.splice(i, 1); + } + } + } + result.position = { left: coords[0][0], top: coords[0][1] }; + } + + return result; + }, + + rect: function(ax, ay, bx, by) { + return { + width: Math.abs(bx - ax), + height: Math.abs(by - ay), + position: { + left: Math.min(ax, bx), + top: Math.min(ay, by) + } + }; + }, + + _angles: { + tc: 3 / 2, tr: 7 / 4, tl: 5 / 4, + bc: 1 / 2, br: 1 / 4, bl: 3 / 4, + rc: 2, lc: 1, c: 0 + }, + ellipse: function(cx, cy, rx, ry, corner) { + var c = PLUGINS.polys._angles[ corner.abbrev() ], + rxc = c === 0 ? 0 : rx * Math.cos( c * Math.PI ), + rys = ry * Math.sin( c * Math.PI ); + + return { + width: (rx * 2) - Math.abs(rxc), + height: (ry * 2) - Math.abs(rys), + position: { + left: cx + rxc, + top: cy + rys + }, + adjustable: FALSE + }; + }, + circle: function(cx, cy, r, corner) { + return PLUGINS.polys.ellipse(cx, cy, r, r, corner); + } +}; +;PLUGINS.imagemap = function(api, area, corner, adjustMethod) +{ + if(!area.jquery) { area = $(area); } + + var shape = (area.attr('shape') || 'rect').toLowerCase().replace('poly', 'polygon'), + image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'), + coordsString = $.trim(area.attr('coords')), + coordsArray = coordsString.replace(/,$/, '').split(','), + imageOffset, coords, i, next, result, len; + + // If we can't find the image using the map... + if(!image.length) { return FALSE; } + + // Pass coordinates string if polygon + if(shape === 'polygon') { + result = PLUGINS.polys.polygon(coordsArray, corner); + } + + // Otherwise parse the coordinates and pass them as arguments + else if(PLUGINS.polys[shape]) { + for(i = -1, len = coordsArray.length, coords = []; ++i < len;) { + coords.push( parseInt(coordsArray[i], 10) ); + } + + result = PLUGINS.polys[shape].apply( + this, coords.concat(corner) + ); + } + + // If no shapre calculation method was found, return false + else { return FALSE; } + + // Make sure we account for padding and borders on the image + imageOffset = image.offset(); + imageOffset.left += Math.ceil((image.outerWidth(FALSE) - image.width()) / 2); + imageOffset.top += Math.ceil((image.outerHeight(FALSE) - image.height()) / 2); + + // Add image position to offset coordinates + result.position.left += imageOffset.left; + result.position.top += imageOffset.top; + + return result; +}; +;PLUGINS.svg = function(api, svg, corner) +{ + var doc = $(document), + elem = svg[0], + root = $(elem.ownerSVGElement), + ownerDocument = elem.ownerDocument, + strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2, + frameOffset, mtx, transformed, viewBox, + len, next, i, points, + result, position, dimensions; + + // Ascend the parentNode chain until we find an element with getBBox() + while(!elem.getBBox) { elem = elem.parentNode; } + if(!elem.getBBox || !elem.parentNode) { return FALSE; } + + // Determine which shape calculation to use + switch(elem.nodeName) { + case 'ellipse': + case 'circle': + result = PLUGINS.polys.ellipse( + elem.cx.baseVal.value, + elem.cy.baseVal.value, + (elem.rx || elem.r).baseVal.value + strokeWidth2, + (elem.ry || elem.r).baseVal.value + strokeWidth2, + corner + ); + break; + + case 'line': + case 'polygon': + case 'polyline': + // Determine points object (line has none, so mimic using array) + points = elem.points || [ + { x: elem.x1.baseVal.value, y: elem.y1.baseVal.value }, + { x: elem.x2.baseVal.value, y: elem.y2.baseVal.value } + ]; + + for(result = [], i = -1, len = points.numberOfItems || points.length; ++i < len;) { + next = points.getItem ? points.getItem(i) : points[i]; + result.push.apply(result, [next.x, next.y]); + } + + result = PLUGINS.polys.polygon(result, corner); + break; + + // Unknown shape or rectangle? Use bounding box + default: + result = elem.getBBox(); + result = { + width: result.width, + height: result.height, + position: { + left: result.x, + top: result.y + } + }; + break; + } + + // Shortcut assignments + position = result.position; + root = root[0]; + + // Convert position into a pixel value + if(root.createSVGPoint) { + mtx = elem.getScreenCTM(); + points = root.createSVGPoint(); + + points.x = position.left; + points.y = position.top; + transformed = points.matrixTransform( mtx ); + position.left = transformed.x; + position.top = transformed.y; + } + + // Check the element is not in a child document, and if so, adjust for frame elements offset + if(ownerDocument !== document && api.position.target !== 'mouse') { + frameOffset = $((ownerDocument.defaultView || ownerDocument.parentWindow).frameElement).offset(); + if(frameOffset) { + position.left += frameOffset.left; + position.top += frameOffset.top; + } + } + + // Adjust by scroll offset of owner document + ownerDocument = $(ownerDocument); + position.left += ownerDocument.scrollLeft(); + position.top += ownerDocument.scrollTop(); + + return result; +}; +;var MODAL, OVERLAY, + MODALCLASS = 'qtip-modal', + MODALSELECTOR = '.'+MODALCLASS; + +OVERLAY = function() +{ + var self = this, + focusableElems = {}, + current, onLast, + prevState, elem; + + // Modified code from jQuery UI 1.10.0 source + // http://code.jquery.com/ui/1.10.0/jquery-ui.js + function focusable(element) { + // Use the defined focusable checker when possible + if($.expr[':'].focusable) { return $.expr[':'].focusable; } + + var isTabIndexNotNaN = !isNaN($.attr(element, 'tabindex')), + nodeName = element.nodeName && element.nodeName.toLowerCase(), + map, mapName, img; + + if('area' === nodeName) { + map = element.parentNode; + mapName = map.name; + if(!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') { + return false; + } + img = $('img[usemap=#' + mapName + ']')[0]; + return !!img && img.is(':visible'); + } + return (/input|select|textarea|button|object/.test( nodeName ) ? + !element.disabled : + 'a' === nodeName ? + element.href || isTabIndexNotNaN : + isTabIndexNotNaN + ); + } + + // Focus inputs using cached focusable elements (see update()) + function focusInputs(blurElems) { + // Blurring body element in IE causes window.open windows to unfocus! + if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); } + + // Focus the inputs + else { focusableElems.first().focus(); } + } + + // Steal focus from elements outside tooltip + function stealFocus(event) { + if(!elem.is(':visible')) { return; } + + var target = $(event.target), + tooltip = current.tooltip, + container = target.closest(SELECTOR), + targetOnTop; + + // Determine if input container target is above this + targetOnTop = container.length < 1 ? FALSE : + (parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[0].style.zIndex, 10)); + + // If we're showing a modal, but focus has landed on an input below + // this modal, divert focus to the first visible input in this modal + // or if we can't find one... the tooltip itself + if(!targetOnTop && target.closest(SELECTOR)[0] !== tooltip[0]) { + focusInputs(target); + } + + // Detect when we leave the last focusable element... + onLast = event.target === focusableElems[focusableElems.length - 1]; + } + + $.extend(self, { + init: function() { + // Create document overlay + elem = self.elem = $('
', { + id: 'qtip-overlay', + html: '
', + mousedown: function() { return FALSE; } + }) + .hide(); + + // Make sure we can't focus anything outside the tooltip + $(document.body).bind('focusin'+MODALSELECTOR, stealFocus); + + // Apply keyboard "Escape key" close handler + $(document).bind('keydown'+MODALSELECTOR, function(event) { + if(current && current.options.show.modal.escape && event.keyCode === 27) { + current.hide(event); + } + }); + + // Apply click handler for blur option + elem.bind('click'+MODALSELECTOR, function(event) { + if(current && current.options.show.modal.blur) { + current.hide(event); + } + }); + + return self; + }, + + update: function(api) { + // Update current API reference + current = api; + + // Update focusable elements if enabled + if(api.options.show.modal.stealfocus !== FALSE) { + focusableElems = api.tooltip.find('*').filter(function() { + return focusable(this); + }); + } + else { focusableElems = []; } + }, + + toggle: function(api, state, duration) { + var docBody = $(document.body), + tooltip = api.tooltip, + options = api.options.show.modal, + effect = options.effect, + type = state ? 'show': 'hide', + visible = elem.is(':visible'), + visibleModals = $(MODALSELECTOR).filter(':visible:not(:animated)').not(tooltip), + zindex; + + // Set active tooltip API reference + self.update(api); + + // If the modal can steal the focus... + // Blur the current item and focus anything in the modal we an + if(state && options.stealfocus !== FALSE) { + focusInputs( $(':focus') ); + } + + // Toggle backdrop cursor style on show + elem.toggleClass('blurs', options.blur); + + // Append to body on show + if(state) { + elem.appendTo(document.body); + } + + // Prevent modal from conflicting with show.solo, and don't hide backdrop is other modals are visible + if((elem.is(':animated') && visible === state && prevState !== FALSE) || (!state && visibleModals.length)) { + return self; + } + + // Stop all animations + elem.stop(TRUE, FALSE); + + // Use custom function if provided + if($.isFunction(effect)) { + effect.call(elem, state); + } + + // If no effect type is supplied, use a simple toggle + else if(effect === FALSE) { + elem[ type ](); + } + + // Use basic fade function + else { + elem.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() { + if(!state) { elem.hide(); } + }); + } + + // Reset position and detach from body on hide + if(!state) { + elem.queue(function(next) { + elem.css({ left: '', top: '' }); + if(!$(MODALSELECTOR).length) { elem.detach(); } + next(); + }); + } + + // Cache the state + prevState = state; + + // If the tooltip is destroyed, set reference to null + if(current.destroyed) { current = NULL; } + + return self; + } + }); + + self.init(); +}; +OVERLAY = new OVERLAY(); + +function Modal(api, options) { + this.options = options; + this._ns = '-modal'; + + this.init( (this.qtip = api) ); +} + +$.extend(Modal.prototype, { + init: function(qtip) { + var tooltip = qtip.tooltip; + + // If modal is disabled... return + if(!this.options.on) { return this; } + + // Set overlay reference + qtip.elements.overlay = OVERLAY.elem; + + // Add unique attribute so we can grab modal tooltips easily via a SELECTOR, and set z-index + tooltip.addClass(MODALCLASS).css('z-index', QTIP.modal_zindex + $(MODALSELECTOR).length); + + // Apply our show/hide/focus modal events + qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function(event, api, duration) { + var oEvent = event.originalEvent; + + // Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop + if(event.target === tooltip[0]) { + if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(OVERLAY.elem[0]).length) { + try { event.preventDefault(); } catch(e) {} + } + else if(!oEvent || (oEvent && oEvent.type !== 'tooltipsolo')) { + this.toggle(event, event.type === 'tooltipshow', duration); + } + } + }, this._ns, this); + + // Adjust modal z-index on tooltip focus + qtip._bind(tooltip, 'tooltipfocus', function(event, api) { + // If focus was cancelled before it reached us, don't do anything + if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; } + + var qtips = $(MODALSELECTOR), + + // Keep the modal's lower than other, regular qtips + newIndex = QTIP.modal_zindex + qtips.length, + curIndex = parseInt(tooltip[0].style.zIndex, 10); + + // Set overlay z-index + OVERLAY.elem[0].style.zIndex = newIndex - 1; + + // Reduce modal z-index's and keep them properly ordered + qtips.each(function() { + if(this.style.zIndex > curIndex) { + this.style.zIndex -= 1; + } + }); + + // Fire blur event for focused tooltip + qtips.filter('.' + CLASS_FOCUS).qtip('blur', event.originalEvent); + + // Set the new z-index + tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; + + // Set current + OVERLAY.update(api); + + // Prevent default handling + try { event.preventDefault(); } catch(e) {} + }, this._ns, this); + + // Focus any other visible modals when this one hides + qtip._bind(tooltip, 'tooltiphide', function(event) { + if(event.target === tooltip[0]) { + $(MODALSELECTOR).filter(':visible').not(tooltip).last().qtip('focus', event); + } + }, this._ns, this); + }, + + toggle: function(event, state, duration) { + // Make sure default event hasn't been prevented + if(event && event.isDefaultPrevented()) { return this; } + + // Toggle it + OVERLAY.toggle(this.qtip, !!state, duration); + }, + + destroy: function() { + // Remove modal class + this.qtip.tooltip.removeClass(MODALCLASS); + + // Remove bound events + this.qtip._unbind(this.qtip.tooltip, this._ns); + + // Delete element reference + OVERLAY.toggle(this.qtip, FALSE); + delete this.qtip.elements.overlay; + } +}); + + +MODAL = PLUGINS.modal = function(api) { + return new Modal(api, api.options.show.modal); +}; + +// Setup sanitiztion rules +MODAL.sanitize = function(opts) { + if(opts.show) { + if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; } + else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; } + } +}; + +// Base z-index for all modal tooltips (use qTip core z-index as a base) +QTIP.modal_zindex = QTIP.zindex - 200; + +// Plugin needs to be initialized on render +MODAL.initialize = 'render'; + +// Setup option set checks +CHECKS.modal = { + '^show.modal.(on|blur)$': function() { + // Initialise + this.destroy(); + this.init(); + + // Show the modal if not visible already and tooltip is visible + this.qtip.elems.overlay.toggle( + this.qtip.tooltip[0].offsetWidth > 0 + ); + } +}; + +// Extend original api defaults +$.extend(TRUE, QTIP.defaults, { + show: { + modal: { + on: FALSE, + effect: TRUE, + blur: TRUE, + stealfocus: TRUE, + escape: TRUE + } + } +}); +;var IE6, + +/* + * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe) + * Special thanks to Brandon Aaron + */ +BGIFRAME = ''; + +function Ie6(api, qtip) { + this._ns = 'ie6'; + this.init( (this.qtip = api) ); +} + +$.extend(Ie6.prototype, { + _scroll : function() { + var overlay = this.qtip.elements.overlay; + overlay && (overlay[0].style.top = $(window).scrollTop() + 'px'); + }, + + init: function(qtip) { + var tooltip = qtip.tooltip, + scroll; + + // Create the BGIFrame element if needed + if($('select, object').length < 1) { + this.bgiframe = qtip.elements.bgiframe = $(BGIFRAME).appendTo(tooltip); + + // Update BGIFrame on tooltip move + qtip._bind(tooltip, 'tooltipmove', this.adjustBGIFrame, this._ns, this); + } + + // redraw() container for width/height calculations + this.redrawContainer = $('
', { id: NAMESPACE+'-rcontainer' }) + .appendTo(document.body); + + // Fixup modal plugin if present too + if( qtip.elements.overlay && qtip.elements.overlay.addClass('qtipmodal-ie6fix') ) { + qtip._bind(window, ['scroll', 'resize'], this._scroll, this._ns, this); + qtip._bind(tooltip, ['tooltipshow'], this._scroll, this._ns, this); + } + + // Set dimensions + this.redraw(); + }, + + adjustBGIFrame: function() { + var tooltip = this.qtip.tooltip, + dimensions = { + height: tooltip.outerHeight(FALSE), + width: tooltip.outerWidth(FALSE) + }, + plugin = this.qtip.plugins.tip, + tip = this.qtip.elements.tip, + tipAdjust, offset; + + // Adjust border offset + offset = parseInt(tooltip.css('borderLeftWidth'), 10) || 0; + offset = { left: -offset, top: -offset }; + + // Adjust for tips plugin + if(plugin && tip) { + tipAdjust = (plugin.corner.precedance === 'x') ? [WIDTH, LEFT] : [HEIGHT, TOP]; + offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ](); + } + + // Update bgiframe + this.bgiframe.css(offset).css(dimensions); + }, + + // Max/min width simulator function + redraw: function() { + if(this.qtip.rendered < 1 || this.drawing) { return this; } + + var tooltip = this.qtip.tooltip, + style = this.qtip.options.style, + container = this.qtip.options.position.container, + perc, width, max, min; + + // Set drawing flag + this.qtip.drawing = 1; + + // If tooltip has a set height/width, just set it... like a boss! + if(style.height) { tooltip.css(HEIGHT, style.height); } + if(style.width) { tooltip.css(WIDTH, style.width); } + + // Simulate max/min width if not set width present... + else { + // Reset width and add fluid class + tooltip.css(WIDTH, '').appendTo(this.redrawContainer); + + // Grab our tooltip width (add 1 if odd so we don't get wrapping problems.. huzzah!) + width = tooltip.width(); + if(width % 2 < 1) { width += 1; } + + // Grab our max/min properties + max = tooltip.css('maxWidth') || ''; + min = tooltip.css('minWidth') || ''; + + // Parse into proper pixel values + perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0; + max = ((max.indexOf('%') > -1 ? perc : 1) * parseInt(max, 10)) || width; + min = ((min.indexOf('%') > -1 ? perc : 1) * parseInt(min, 10)) || 0; + + // Determine new dimension size based on max/min/current values + width = max + min ? Math.min(Math.max(width, min), max) : width; + + // Set the newly calculated width and remvoe fluid class + tooltip.css(WIDTH, Math.round(width)).appendTo(container); + } + + // Set drawing flag + this.drawing = 0; + + return this; + }, + + destroy: function() { + // Remove iframe + this.bgiframe && this.bgiframe.remove(); + + // Remove bound events + this.qtip._unbind([window, this.qtip.tooltip], this._ns); + } +}); + +IE6 = PLUGINS.ie6 = function(api) { + // Proceed only if the browser is IE6 + return BROWSER.ie === 6 ? new Ie6(api) : FALSE; +}; + +IE6.initialize = 'render'; + +CHECKS.ie6 = { + '^content|style$': function() { + this.redraw(); + } +}; +;})); +}( window, document )); diff --git a/plugins/jetpack/changelog.txt b/plugins/jetpack/changelog.txt index 595b0b9..6413283 100644 --- a/plugins/jetpack/changelog.txt +++ b/plugins/jetpack/changelog.txt @@ -1,1787 +1,1787 @@ -== Changelog == - -= 4.0.4 = -Release date: June 20th, 2016 -Release Post: http://wp.me/p1moTy-3eT - -Security: - -* Post By Email: Added an additional layer of security to prevent unauthorized changes to Post By Email settings. -* Likes: Fixed an XSS vulnerability in the Likes module. -* REST API/Contact Form: We've eliminated unauthenticated access to Feedback posts. - -Feature Improvements: - -* Customizing Protect: We've increased Protect’s response time and added a new filter, `jetpack_protect_connect_timeout`, reducing the likelihood of seeing the fall back form. -* Connection Process: Your site url and icon are displayed on the Jetpack connection screens to help improve communication. -* Jetpack for Multisite: It’s now easier to manage your Jetpack connections on the network admin screen. -* Photon Responsive Image Improvements: We’re now auto-generating new scrset options, improving how images served from Photon are handled. -* Developing on Kinsta: A new constant has been added to improve developing with Jetpack on a staging environment hosted with Kinsta. - -Jetpack UI Improvements: - -* Better Access to Our Support Team: We wanted to make it easier for you to get help so we added a contact form in the admin that links directly to our Jetpack Support Team. - -Improved Compatibility: - -* We’ve stopped adding Open Graph Meta tags if you’re using the SEO Framework plugin. -* Having both GlotPress and Jetpack active at the same time was causing errors, we’ve eliminated them. - -Bug Fixes: - -* Fixed the handling of special characters like ampersands in Carousel Titles and Descriptions. -* When visitors tried to view a Carousel image with a hash in the URL, a JavaScript error would occur; we’ve fixed that. -* Jetpack Comment form fields now use the default language you’ve set for WordPress, previously the verbiage was always in English. -* Custom CSS wasn’t handling slashes and quotes properly; we’ve squashed that bug. -* There were some rare cases where PHP notices were popping up when a Contact Form was submitted. These instances have been identified and eliminated. -* We’ve replaced a bit of code with a Jetpack native function to fix a bug that was breaking things during an API request for available updates. -* We accidentally removed the ability for Open Graph to select images from slideshows, it’s up and running again. -* There was an issue where Open Graph meta tags weren’t being set when your homepage is a “Static Front Page”, it’s working again. -* In rare cases when developers were customizing Photon they were seeing a PHP notice when arguments were passed as a string rather than an array. This has been fixed. -* We’ve fixed an issue where Protect’s backup math form wasn’t showing on custom frontend login forms. -* When setting up WooCommerce you might have seen a Related Posts notice which didn’t belong. We’ve eliminated them. -* If you’ve been using our sharing tool with unofficial sharing buttons you might have noticed your sharing numbers were missing. They’re now back. -* In unique situations where special characters were used in sitemap stylesheets an error would occur; that has been remedied. -* We’ve fixed a problem with mismatching HTML tags in our Spelling and Grammar feature. -* We’ve ensured that the `jetpack_disable_twitter_cards` filter actually removes Twitter cards. -* We’ve fixed some JavaScript errors that would crop up if you were editing a custom-post-type post that didn’t support the core media editor — say that 10 times fast. -* We had some JavaScript errors when you were using the customizer to modify widgets. They are no longer with us. - -= 4.0.3 = -Release date: May 26th, 2016 -Release Post: http://wp.me/p1moTy-3hm - -* Important security update. Please upgrade immediately. - -= 4.0.2 = -Release date: April 21st, 2016 - -Bug Fix: - -* Addresses an issue where Jetpack 4.0 caused a fatal error on sites with specific configurations. - -= 4.0 = -Release date: April 20th, 2016 -Release Post: http://wp.me/p1moTy-3dL - -Performance Enhancements: - -* Protect: the routine that verifies your site is protected from brute-force attacks got some love and is more efficient. -* Contact Forms: cleaning the database of spam form submission records is more efficient. - -Feature Improvements: - -* VideoPress: edit your VideoPress shortcode in the editor with a fancy new modal options window. -* Custom Content Types are now classier: a new CSS class on Testimonial featured images — has-testimonial-thumbnail — allows you to customize Jetpack custom post types as you see fit. -* Sharing: social icons are now placed under the "add to cart” singular product views in WooCommerce, making it easier for customers to share your products on social media. -* Theme Tools: search engines will now have an easier time knowing what page they are on, and how that page relates to the other pages in your site hierarchy with improved schema.org microdata for breadcrumbs. -* Widget Visibility: now you can select widgets and when to show or hide them right from custom post type single and archive views. - -Jetpack UI Improvements: - -* What’s in it for me? We’ve done a better job explaining the benefits of Jetpack and connecting it to WordPress.com. -* Shortcodes: handy links to shortcode documentation convey the types of media you can quickly and safely embed. -* Widgets: As of WordPress 4.5, Jetpack widgets now refresh in the customizer without making you refresh the entire page. Live previews, yes indeed. - -Bug Fixes: - -* Comments: we fixed a mistake where a comment subscription checkbox appeared on custom post types — despite the fact you couldn’t actually subscribe to those types of comments. Our bad. -* Contact Forms: we fixed a bug where the telephone field (which can only be added manually) rendered incorrectly — breaking some forms in the process. -* General: we blocked direct access to the Jetpack_IXR_Client class which caused fatal PHP errors in some server setups. -* Shortcodes: we removed the frameborder attribute in the YouTube embed code. It was deprecated in HTML 5. -* Unminified responsive-videos.min.js in order to address a false positive virus alert in ClamAV. Expect it to be re-minified in 4.0.3 once we resolve the issue with ClamAV. - -= 3.9.6 = -Release date: March 31st, 2016 -Release Post: http://wp.me/p1moTy-3bz - -Bug fix: Shortcodes: fixed incorrect Vimeo embed logic. - -= 3.9.5 = -Release date: March 31st, 2016 -Release Post: http://wp.me/p1moTy-3bz - -This release features several WordPress 4.5 compatibility changes that make several Jetpack features work properly in the Customizer view. Big thanks to @westonruter for contributing the code! - -Other enhancements and bug fixes: - -* Contact Form: no longer calling the datepicker method if it's not available. -* SSO: settings checkboxes now honor filters and constants that restrict certain sign-in modes. -* Shortcodes: fixed a problem with Gist fetching. -* Shortcodes: fixed invalid HTML5 markup in YouTube embed code. -* Shortcodes: made the Vimeo links work properly in case of multiple mixed uses in one post. - -= 3.9.4 = -Release date: March 10th, 2016 -Release post: http://wp.me/p1moTy-396 - -Bug fix: Shortcodes: Addresses an issue with embedded Vimeo content - -= 3.9.3 = -Release date: March 9th, 2016 -Release post: http://wp.me/p1moTy-396 - -Featured: - -* Site Logo now supports Custom Logo - a theme tool to be introduced in WordPress 4.5. - -Enhancements: - -* Carousel: Made the full size image URL use a Photon URL if enabled. -* Comments: Removed an unnecessary redirect by always connecting via HTTPS. -* General: Added new actions that fire before automatic updates. -* Infinite Scroll: Introduced a later filter for settings. -* Infinite Scroll: Removed code that is now redundant due to WordPress Core. -* Markdown: Removed deprecated markup from the output. -* Publicize: Improved handling of featured images in posts. -* Shortcodes: Added houzz.com support. -* Sitemaps: Added a language attribute to the news sitemap. -* Sitemaps: Improved the image retrieval mechanism for posts. -* Widgets: Added new filters in the Top Posts Widget code. -* Widgets: Cleaned up the CSS for the Subscription widget. - -Bug Fixes: - -* Comments: No longer reloading the page on clicking the reply button. -* Contact Forms: Fixed a fatal error on missing metadata. -* Contact Forms: Fixed message formatting for plaintext email clients. -* Shortcodes: Fixed dimensions of Vimeo embeds in certain cases. -* Shortcodes: Fixed warnings and allowed shorter style Vimeo embeds. -* Shortcodes: Removed alignment markup from feeds for YouTube embeds. -* Sitemaps: Made URLs display properly according to the permalink structure. -* Stats: Fixed non-XHTML-valid markup. -* Widgets: No longer showing errors when adding new instances of the Display Post Widget. - -= 3.9.2 = -Release date: February 25th, 2016 -Release post: http://wp.me/p1moTy-2Ei - -Maintenance and Security Release - -Featured: - -* Beautiful Math: fix XSS vulnerability when parsing LaTeX markup within HTML elements. -* Contact Form: do not save private site credentials in post meta. Thanks to @visualdatasolutions. - -Enhancements: - -* Contact Info: Added two hooks for adding arbitrary information to the widget. -* Development: Added new possibilities for REST API debugging. -* Embeds: Added Codepen embeds support. -* Embeds: Added Sketchfab embeds support. -* I18n: Added support for translation packages for the Finnish language. -* Markdown: Added a filter to enable skipping processing of developer supplied patterns. -* Related Posts: Added a filter to change heading markup. -* Staging: Added a constant to force staging mode. -* Staging: Added a notice to make staging mode more obvious. -* Top Posts Widget: Added a new `[jetpack_top_posts_widget]` shortcode. - -Bug Fixes: - -* Custom Post Types: Nova: Fixed a JavaScript bug on adding multiple items. -* Embeds: Allowing embeds from Instagram with a www in an URL. -* General: Fixed untranslated module names on the Settings screen. -* General: Improved module descriptions and fixed misleading or broken links in descriptions. -* General: No more notices on module deprecation on older installations. -* General: Only showing one prompt to enable Photon when uploading several new images. -* Multisite: Fixed a problem with site lists for older WordPress installations. -* OpenGraph: Fixed a bug to properly fallback to a WordPress Site Icon image. -* Photon: Improve performance for images over a secure connection. -* Photon: No longer including links from data attributes. -* Publicize: Fixed problems for en_AU and en_CA locales with Facebook. -* Related Posts: Fixed a notice on certain requests. -* Site Logo: It's no longer possible to choose a non-image. -* Widget Visibility: No longer confusing page IDs and titles in certain cases. - -= 3.9.1 = -Release date: January 21st, 2016 - -Bug Fixes: - -* General: Addresses a namespacing issue which was causing conflicts on some hosting providers. -* Sitemaps: Added MSM-Sitemap to the list of plugins which, if installed, will prevent Jetpack Sitemaps from being used - -= 3.9 = -Release date: January 20th, 2016 -Release Post: http://wp.me/p1moTy-29R - -Featured: - -* New sharing button: let users share your content using Skype. -* New "Social Menu" theme tool that uses Genericons to display Social Links. -* Sitemap support for better search engine indexing. - -Enhancements: - -* Contact Form: Added a new filter that allows you to change the "Required" text. -* General: Hidden archived sites in multisite site list. -* General: Removed several function calls that would be deprecated in WordPress 4.5. -* Infinite Scroll: Added a new filter to check if Infinite Scroll has been triggered. -* Likes: Added a conditional to ensure WordPress 4.5 compatibility. -* Photon: Improved compatibility with responsive images feature added in WordPress 4.4. -* Photon: Now enabled by default on sites using HTTPS. -* REST API: Extended the ability to manage users from WordPress.com. -* REST API: Increased the performance of the plugin update endpoint. -* Responsive Videos: Centering videos when they are wrapped in a centered paragraph. -* Sharing: Added a new filter to customize the default OpenGraph description. -* Shortcodes: Added Wistia oEmbed support. -* Shortcodes: Bandcamp: Added support for new attributes for tracks approved by artists. -* Shortcodes: Improved Medium path format recognition. -* Slideshow: Improved compatibility with older IE versions. -* Staging: Improved staging environment detection. -* Widgets: Added "width" option to the Facebook Page widget. -* Widgets: Added size parameters to tags in Top Posts to avoid warnings. -* Widgets: Introduced major performance and stability improvements to the Display Posts Widget. -* Widgets: Refactored to remove deprecated code patterns. - -Bug Fixes: - -* AtD: Fixed replacing emojis with images in the text editor in Chrome. -* AtD: Made pre tags be excluded from spell-checking. -* CPT: Not registering Nova if it is already registered. -* Carousel: Fixed a bug where full size images were not always served by Photon. -* Carousel: Reverted a change that broke direct link to carousel image. -* Contact Form: Fixed a CSV export bug with multiple choice questions. -* Contact Form: Fixed notices when creating feedback entries without a contact form. -* General: Fixed a scrolling bug on modal window closing. -* Infinite Scroll: Disabled in the Customizer when previewing a non-active theme. -* Publicize: Fixed notices appearing with bbPress or BuddyPress installed. -* Publicize: Showing options only to users that can change them. -* Related Posts: Fixed incorrect URLs generated for posts. -* Responsive Videos: Fixed warnings in debug mode. -* Shortcodes: Bandcamp: Fixed a problem with large track IDs. -* Shortcodes: Fixed a problem with dynamic Gist embeds. -* Stats: Fixed dashboard widget resize problem. -* Widgets: Added a fallback to English US when a locale isn't supported by Facebook. -* Widgets: Fixed layout for Twenty Sixteen. - -= 3.8.2 = -Release date: December 17th, 2015 -Release post: http://wp.me/p1moTy-26v - -Jetpack 3.8.2 is here to squash a few annoying bugs. - -Bug Fixes: - -* Photon: Fixed a bug where some custom thumbnail image sizes weren't being sized properly. -* Shortcodes: Fixed an incompatibility with how WordPress renders the YouTube shortcode. -* Shortcodes: Tightened up security in the Wufoo shortcode. -* Image Widget: Now shows the caption. -* Fixed typos in inline docs. -* Very minor fixes to: Carousel, Publicize, Google+, and Infinite Scroll. - -= 3.8.1 = -Release date: December 1st, 2015 -Release post: http://wp.me/p1moTy-23V - -Jetpack 3.8.1 is here and is fully compatible with WordPress 4.4. - -Featured: - -* Photon + Responsive Images FTW. -* Fully compatible with Twenty Sixteen. -* More accessibility enhancements. -* Dropped some weight by optimizing Jetpack's plugin images. - -Enhancements: - -* Comments: filter to allow disabling comments per post type. - -Bug Fixes: - -* Carousel: Stop page from scrolling to top when Carousel is closed. -* Carousel: Browser compatibility fixes with older version of IE. -* Markdown: Fixed a bug that would strip markdown when saving in "Quick Edit" mode. -* Single Sign On: Fixed login always redirecting to the admin dashboard. -* Subscriptions: Filter to allow per-post emails fixed for use in themes. - -= 3.8.0 = -Release date: November 4th, 2015 -Release post: http://wp.me/p1moTy-1VN - -We're happy to introduce Jetpack 3.8, which has significant contributions from the Jetpack community. Read more about it here: http://wp.me/p1moTy-1VN - -Feature enhancements: - -* New Google+ Badge Widget. Display your profile, page, or community Google+ badge. -* New twitch.tv shortcode embeds. Display a Twitch.tv stream in your posts. -* Accessibility enhancements. -* A handful of new filters to allow further customization of Jetpack. - -Other enhancements: - -* Carousel: Added support to retrieve image dimensions from an image url. -* Carousel: Simpler algorithm to detect shutter speeds. -* Contact Form: New "Checkbox with Multiple Items" field available in the Contact Form. -* Contact Form: Allow pre-filling form fields with URL parameters. -* Contact Form: Better styling of the emailed form responses. -* Performance: Replaced some custom-built functions with core's native functions. -* Related Posts: New filter to add post classes to post's container class. -* Sharing: New filter to choose if sharing meta box should be shown. -* Sharing: New filter to allow sharing button markup to be editable. -* Sharing: New filter to allow you to specify a custom Facebook app ID. -* Social Media Icons Widget: Added option for YouTube username as well as Channel ID. -* Social Media Icons Widget: Added Google+ icon. -* Social Media Icons Widget: New filter to allow you to add your own social media icons and links. -* Subscriptions: Better errors to your visitors if their subscription sign-up fails. -* Subscriptions: Removed "widget" class from Subs shortcode form. - - -Bug fixes: - -* Carousel: Fixed browser back/forward button behavior. -* Contact Form: Allow the email field to be set to empty when building form in post editor. -* Facebook Likebox Widget: Fixed an issue where some languages were not translating. -* Facebook Likebox Widget: Return a language when none found. -* General: Fixed some minor styling issues in the Jetpack admin areas. -* General: Add missing parameter to the_title filter call. -* General: Prevent scrolling of body when the Jetpack admin modals are opened. -* General: Update doc to reflect that Open Graph filter jetpack_enable_opengraph has been deprecated in favor of jetpack_enable_open_graph. -* Infinite Scroll: Fixed an error that sometimes occurred that would stop posts from loading. -* JSON API: Fixed some undefined notices when publishing a post with the API. -* Open Graph: Fixed bug where facebook description content was sometimes being polluted by a filter. -* Sharing: Use full SSL Pinterest url instead of protocol relative. -* Sharing: Fixed plus signs appearing in tweets shared from iOS. -* Shortcodes: Prefer HTTPS for video embeds to avoid mixed content warnings. -* Subscriptions Widget: Fix HTML Validation error. -* Theme Tools: Check oEmbeds for the presence of a video before adding the responsive videos filter. -* Tiled Galleries: Add image alt attribute if there is a title set. This was breaking some screen reader functionality. - -= 3.7.2 = -Release date: September 29th, 2015 -Release Post: http://wp.me/p1moTy-1LB - -* Bug Fix: REST API: Fixed an error when saving drafts and publishing posts - -= 3.7.1 = -Release date: September 28th, 2015 -Release Post: http://wp.me/p1moTy-1LB - -* Enhancement: General: Added inline documentation for various filters and functions -* Enhancement: General: Added custom capabilities for module management on multi-site installs -* Enhancement: General: Cleaned up old changelog entries from readme -* Enhancement: General: Cleaned up unused i18n textdomains -* Enhancement: General: Updated the new settings page to look better in various translations -* Enhancement: REST API: Added new endpoints to manage users -* Enhancement: Sharing: Updated the Google logo -* Bug Fix: Carousel: Page scroll no longer disappears after closing the carousel -* Bug Fix: Contact Form: Fields are sent and displayed in the correct order -* Bug Fix: Contact Form: No longer showing a notice on AJAX actions in feedback lists -* Bug Fix: Contact Form: Made using more than two notification emails possible -* Bug Fix: Contact Form: Mitigate a potential stored XSS vulnerability. Thanks to Marc-Alexandre Montpas (Sucuri) -* Bug Fix: General: Mitigate a potential information disclosure. Thanks to Jaime Delgado Horna -* Bug Fix: General: Fixed a locale error in the notifications popout -* Bug Fix: General: Fixed a possible fatal error in the client area -* Bug Fix: General: Fixed compatibility issues with certain use cases -* Bug Fix: General: Disabled connection warnings for multisites with domain mapping -* Bug Fix: General: Updated translations for correct link display in admin notices -* Bug Fix: REST API: Fixed a fatal error in one of the endpoints -* Bug Fix: Sharing: Fixed OpenGraph tags for Instagram embeds -* Bug Fix: Sharing: Fixed compatibility issues with bbPress -* Bug Fix: Widget Visibility: Fixed a fatal error in case of a missing tag - -= 3.7.0 = -Release date: September 9th, 2015 -Release Post: http://wp.me/p1moTy-1JB - -Feature Enhancements: - -* New admin page interface to easily configure Jetpack -* Added staging site support for testing a connected Jetpack site - -Additional changes: - -* Enhancement: CLI: Added a possibility to change all options with confirmation for some of them -* Enhancement: Gallery: Added filters to allow new gallery types to be declared -* Enhancement: General: Added inline documentation for actions, filters, etc. -* Enhancement: General: Changed class variable declarations keyword from var to public -* Enhancement: General: Made the Settings page module toggle buttons more accessible -* Enhancement: General: The admin bar now loads new notifications popout -* Enhancement: General: Renamed some modules to avoid redundant prefixes -* Enhancement: General: Switched to the WordPress Core's spinner image -* Enhancement: General: Updated the bot list -* Enhancement: Manage: Added the ability to activate a network-wide plugin on a single site from WordPress.com -* Enhancement: Photon: Added a way to check image URLs against custom domains -* Enhancement: Photon: Added prompts on the media upload page telling the user about Photon -* Enhancement: Publicize: Added width and height values to OpenGraph tags for default images -* Enhancement: Related Posts: Added a filter to allow disabling nofollow -* Enhancement: REST API: Added new API endpoints to extend API functionality -* Enhancement: REST API: Added new fields to existing API endpoints -* Enhancement: Sharing: Added a possibility to opt-out of sharing for a single post -* Enhancement: Sharing: Added bbPress support -* Enhancement: Sharing: Added more configuration to the Likes modal -* Enhancement: Sharing: Made the reddit button open a new tab -* Enhancement: Sharing: Removed unused files -* Enhancement: Shortcodes: Added auto embed option inside comments -* Enhancement: Shortcodes: Added autohide parameter to the YouTube shortcode -* Enhancement: Subscriptions: added an action that triggers at the end of the subscription process -* Enhancement: VideoPress: Videos are now embedded using a new player -* Enhancement: Widget Visibility: Added parent page logic -* Enhancement: Widget Visibility: Added support for split terms -* Enhancement: Widgets: Added actions to the Social Media widget -* Enhancement: Widgets: Switched the Display Posts widget to the new API version -* Bug Fix: General: Fixed scrolling to top after modal window closing -* Bug Fix: Infinite Scroll: Added a check for cases when output buffering is disabled -* Bug Fix: Infinite Scroll: Added translation to the copyright message -* Bug Fix: Manage: Fixed automatic update synchronization on WordPress multisite network admin -* Bug Fix: Manage: Redirects back to WordPress.com are allowed from the customizer view -* Bug Fix: Media: Fixed duplicate images bug in the Media Extractor -* Bug Fix: Publicize: Made it possible to remove previously set message -* Bug Fix: Sharing: Added a thumbnail image to OpenGraph tags on pages with DailyMotion embeds -* Bug Fix: Sharing: Fixed Twitter Cards tags escaping -* Bug Fix: Sharing: Made OpenGraph tags for title and description use proper punctuation -* Bug Fix: Sharing: Made sure Likes can be disabled on the front page -* Bug Fix: Shortcodes: Fixed Facebook embeds by placing the scipt in the footer -* Bug Fix: Shortcodes: Fixed PollDaddy shortcode issues over SSL connections -* Bug Fix: Shortcodes: Made responsive video wrappers only wrap video embeds -* Bug Fix: Shortcodes: Made SoundCloud accept percents for dimensions -* Bug Fix: Social Links: Fixed a possible conflict with another class -* Bug Fix: Stats: Made sure the Stats URL is always escaped properly - -= 3.6.1 = -Release Date: July 24, 2015 - -* Enhancement: Fully compatible with upcoming WordPress 4.3 -* Enhancement: Site Icon: Start to deprecate Site Icon in favor of Core's version (if available) -* Bug Fix: Subscriptions: You can now use more than one Subscription form on a single page -* Bug Fix: Quieted PHP notices and warnings with the JSON API, Display Posts Widget and Gallery Widget (slideshow mode) -* Bug Fix: Correct permissions check for connection panel -* Hardening: Increase permissions checks - -= 3.6 = -Release Date: July 6th, 2015 -Release Post: http://wp.me/p1moTy-1ua - -Feature Enhancements: - -* CLI: Add a number of Jetpack CLI improvements: see http://jetpack.com/support/jetpack-cli -* New Jetpack admin page for connection management -* New Social Media Icons widget -* FB Like Box: A visual refresh of the Facebook likebox widget -* Protect: When your IP is blocked, use a math captcha as a fallback instead of a complete block - -Additional changes: - -* Enhancement: Custom CSS: Add more Flexbox support and other enhancements -* Enhancement: Extra Sidebar Widgets: Top Posts Widget: Choose what Post Types to display -* Enhancement: General: Save on some requests! print CSS inline when there isn't much of it -* Enhancement: Likes: Likes can now be shown on all post types -* Enhancement: Minileven: Add Featured Image to Gallery Post Format and Pages -* Enhancement: Mobile Theme: Add div wrapping View Mobile Site link to allow for easier CSS customizations -* Enhancement: Omnisearch: Link to edit post in titles -* Enhancement: Protect: Learn Trusted Headers locally and cache blocks properly -* Enhancement: REST API: Add locale support -* Enhancement: Sharing: Retire StumbleUpon -* Enhancement: Sharing: Upgrade to reCAPTCHA 2.0 for Email Sharing -* Enhancement: Shortcode Embeds: Add Mesh oembed support -* Enhancement: Shortcode Embeds: New Wufoo Shortcode from WordPress.com -* Enhancement: Shortcode Embeds: Mixcloud: handle accented characters in URLs -* Enhancement: Site Logo: Adding itemprops to support logo schema. -* Enhancement: Slideshow Gallery: New parameters *size* and *autostart* -* Enhancement: Slideshow Gallery: Use more reliable CSS for resizing instead of js -* Enhancement: Stats: No longer track stats for preview pages -* Enhancement: Tiled Gallery: Improve the shapes and distributions of shapes in the Tiled Gallery, based on observations for its usage. -* Enhancement: Protect: Whitelist for multisite globally and locally -* Enhancement: Sharing: LinkedIn always uses https for share counts. (saved extra http request) -* Bug Fix: Carousel: Jetpack Carousel now supports HTML5 gallery -* Bug Fix: Extra Sidebar Widgets: Choose Images button works in accessibility mode -* Bug Fix: General: Fix: Cannot remove hooks from filter 'jetpack_get_available_modules' -* Bug Fix: Infinite Scroll: Check that search terms exist before matching against post title. fixes #2075 -* Bug Fix: Likes: Never double show on search results -* Bug Fix: Notifications: Notifications didn't load on wp-admin/network pages -* Bug Fix: Sharing: Fix Facebook share button not showing for Australian & Canadian locale -* Bug Fix: Shortcode Embed: Slideshare Shortcode now fixed -* Bug Fix: SSO: Hide login no matter what when using the filter to do so -* Bug Fix: Subs Widget: Don't hide email input if submit failed -* Bug Fix: Tiled Gallery: Show columns setting for Thumbnail Grid when Tiled Mosaic galleries are the default -* Bug Fix: Twitter Cards: Remove deprecated card types - -= 3.5.3 = -Release Date: May 6th, 2015 - -* Security Hardening: Remove Genericons example.html file. - -= 3.5.2 = -Release Date: May 5th, 2015 - -* Bug Fix: Sharing: Changes Facebook share count endpoint - - -= 3.5.1 = -Release Date: May 5th, 2015 - -* Enhancement: Sharing: Changes Facebook share count method per Facebook API change -* Enhancement: General: Remove .po files to reduce plugin size -* Bug Fix: General: Remove identity crisis notification -* Bug Fix: Subscriptions: Correct required input validation -* Security hardening - -= 3.5 = -Release Date: April 23rd, 2015 -Release Post: http://wp.me/p1moTy-1jF - -Jetpack 3.5 introduces the ability to manage your site's menus directly from WordPress.com and several bug fixes and enhancements. This upgrade is recommended for all users. - -* Enhancement: General: Change security reporting to use a transient instead of option to reduce backup load -* Enhancement: General: Improve module search -* Enhancement: JSON API: Allow users to manage menus through WordPress.com -* Enhancement: Sharing: Reduce spam through email sharing -* Bug Fix: Custom CSS: Improve recall of CSS revisions -* Bug Fix: Extra Sidebar Widgets: Change class name for Contact Info widget -* Bug Fix: Extra Sidebar Widgets: Fix errors when adding widgets via the customizer -* Bug Fix: Extra Sidebar Widgets: Fix PHP notices in RSS widget -* Bug Fix: General: Fix redirect loop on activation -* Bug Fix: General: Styling fixes -* Bug Fix: Protect: Add IP translation fallback when inet_pton is not available -* Bug Fix: Protect: Always allow login from local IDs -* Bug Fix: Protect: Sanitize displayed IP after block -* Bug Fix: Publicize: Prevent generating Facebook profile links for app-scoped user IDs -* Bug Fix: Subscriptions: Improve error handling -* Bug Fix: Theme Tools: Include breadcrumb code -* Misc: Extra Sidebar Widgets: Remove Readmill Widget - -= 3.4.3 = -Release Date: April 20th, 2015 -Release Post: http://wp.me/p1moTy-1jb - -* Security hardening. - -= 3.4.2 = -Release Date: April 19th, 2015 -Release Post: http://wp.me/p1moTy-1j6 - -* Bug Fix: Contact info widget namespacing -* Bug Fix: Javascript errors on wp-admin due to stats display code -* Bug Fix: Potential fatal error from improperly called function -* Bug Fix: Potential fatal error when protect servers are unreachable for WordPress Multisite - -= 3.4.1 = -Release Date: March 19th, 2015 - -* Bug Fix: General: Modules not displaying properly in non-English installs -* Bug Fix: Manage: Some installs showing a transient fatal error -* Bug Fix: Protect: Protect module not auto-activating for users who upgrade -* Bug Fix: Omnisearch: Some installs not properly reporting WP version number, causing Omnisearch error -* Bug Fix: Stats: Top posts/pages widget not loading -* Bug Fix: Contact Info Widget: Fix conflict with Avada theme - -= 3.4 = -Release Date: March 18th, 2015 -Release Post: http://wp.me/p1moTy-1fU - -* Enhancement: Config Settings: provide a notification for users that update features settings -* Enhancement: Config Settings: provide a notification for users that update features settings -* Enhancement: Contact Form: Use the predefined $title variable in the anchor tag in grunion contact form button -* Enhancement: Contact Form: Use the predefined $title variable in the anchor tag in the button on admin -* Enhancement: Custom Content Type: Add all Custom Post Types to Omnisearch -* Enhancement: Custom Content Type: Add option to add Testimonial Custom Content Type in admin -* Enhancement: Custom Content Type: bring consistency between the portfolio and testimonial shared codebase -* Enhancement: Custom Content Type: code cleanup -* Enhancement: Custom Content Type: register namespaced 'jetpack_portfolio' shortcode/use a prefix for shortcode for Portfolio -* Enhancement: Custom Content Type: set shortcode image size to 'large' and add jetpack_portfolio_thumbnail_size filter to allow themes to set their own size for Portfolio -* Enhancement: Custom Content Type: testimonial shortcode enhancement -* Enhancement: Extra Sidebar Widgets: Add subscription widget wildcard -* Enhancement: Extra Sidebar Widgets: Likes and Sharing Shortcodes -* Enhancement: Extra Sidebar Widgets: Minor fixes to Facebook widget plugin for SSL -* Enhancement: Fix/update jetpack version -* Enhancement: General: Add DNS Prefetching -* Enhancement: General: Add Jetpack admin dashboard widget -* Enhancement: GlotPress: Update GP_Locales and GP_Locale classes -* Enhancement: Improved control over Nova Theme Menu output markup -* Enhancement: Infinite Scroll: Adds a `button` wrapper for the infinity handle. -* Enhancement: Infinite Scroll: Check for response.html before using indexOf -* Enhancement: Integrate BruteProtect for protection against Brute Force attacks -* Enhancement: JSON API Manage: Added Mock Jetpack Option to Sync options that don't have to live in the Database -* Enhancement: JSON API: Add/empty trash days option to sync -* Enhancement: Jump Start: Add "Jump Start" interface for new users -* Enhancement: Manage: Add "modified_before" and "modified_after" parameters to /sites/%s/posts/ via JSON API -* Enhancement: Mobile Theme: Add filter for choosing mobile theme menu -* Enhancement: Notifications: Changes to load the new notifications client. -* Enhancement: Protect: Add a filter so that user can add thier own bots -* Enhancement: Protect: Add security reporting -* Enhancement: Protect: Add/whitelist endpoints via JSON API for Jetpack Protect -* Enhancement: Publicize: update connection confirmation message -* Enhancement: Sharing: Add custom service name as a class -* Enhancement: Sharing: display name of custom service in link title -* Enhancement: Sharing: Remove default post types for showing share links -* Enhancement: Sharing: use Jetpack version number when enqueing sharing.js -* Enhancement: Shortcodes Team Partnerships: Backport fixes from SoundCloud 2.3.1 through 3.0.2 -* Enhancement: Shortlinks: use HTTPS when possible -* Enhancement: Stats: Make loading of stats async -* Enhancement: Subscriptions: Added settings field for comment sub text -* Enhancement: Subscriptions: Hide Form After Submit -* Enhancement: Subscriptions: remove label from widget title -* Enhancement: Subscriptions: Update subscriptions.php -* Bug Fix: Contact form: Increase CSS specificity for Contact Forms in widgets -* Bug Fix: Custom Content Type: Testimonial Custom Content Type: use core `WP_Customize_Image_Control` instead of custom... -* Bug Fix: Extra Sidebar Widgets: add missing & to if statement for widget visibility -* Bug Fix: Extra Sidebar Widgets: Don't require height/width values in the Twitter Timeline widget -* Bug Fix: Extra Sidebar Widgets: Upload images from the customizer/Extra Sidebar Widgets Tiled Galleries for Gallery Widget -* Bug Fix: General: Fix bug that was preventing modules from displaying properly -* Bug Fix: Manage: When calling /sites/%s/posts/ include all attachments not just the first five via JSON API -* Bug Fix: Mobile Theme: Minileven; Start after DOM ready -* Bug Fix: Sharing: Open sharing in same window -* Bug Fix: Stats language -* Bug Fix: Subscritpions: fix invalid field when no email address - - -= 3.3.2 = -Release Date: February 19th, 2015 - -* Enhancement: Updated translation files. -* Enhancement: Heartbeat: Correctly stat new datasets. -* Bug Fix: Widget Visibility: Correct some caching of visibility results that may get evaluated too soon. -* Bug Fix: Contact Form: Hardening. -* Bug Fix: Photon: Make sure our gallery filter can parse array inputs as well as the default html. - -= 3.3.1 = -Release Date: February 11th, 2015 - -* Bug Fix: JSON API: Minor versioning data. -* Bug Fix: Markdown: Re-run KSES after processing to account for syntax changes. -* Bug Fix: Media Extractor: Don't call a gallery a gallery if it hasn't got any pictures! -* Bug Fix: Module Management: Handle a core api change for folks running trunk. -* Bug Fix: Related Posts: CSS -- better clear rows. -* Bug Fix: Sharing: Including sharing account on Pinterest unofficial buttons as well. -* Bug Fix: Sharing: Properly version external assets by Jetpack release version. -* Bug Fix: Shortcodes: Soundcloud: Backport API compatibility fixes. -* Bug Fix: Shortcodes: Flickr: Tidy up our regex url pattern matching. -* Bug Fix: Subscriptions: Don't add 'Email Address' as the value -- we have placeholders! -* Bug Fix: Widgets: Gallery Widget: Allow folks to upload images from the widget area in the customizer. - -= 3.3 = -Release Date: December 15th, 2014 -Release Post: http://wp.me/p1moTy-1aF - -* Enhancement: Adds responsive video support to BuddyPress. -* Enhancement: Custom Content Types: Added 'order' and 'orderby' options to portfolio shortcode. -* Enhancement: Display notice when Jetpack Development Mode is on. -* Enhancement: General: Update compatibility with Twenty Fifteen. -* Enhancement: Image URL can now be overwritten with the `jetpack_images_fit_image_url_override` filter after dimensions are set by Photon. -* Enhancement: JSON API: Add Endpoint for trigger Plugin Autoupdates. -* Enhancement: JSON API: General Improvements. Documentation on http://developer.wordpress.com/ -* Enhancement: Likes: Updated the code to accept arbitrary CPTs. -* Enhancement: Related Posts: Allow filter by `post_format`. -* Enhancement: Sharing: add new `jetpack_sharing_counts` filter for option to turn off sharing counts. -* Enhancement: Sharing: Use the Site Logo Theme Tool and the Site Icon as fallbacks for image tags. -* Enhancement: Shortcodes: Made the code more readable by using output buffers instead of string concatenation. -* Enhancement: Site Logo: Add alias functions to provide backward compatibility for themes expecting the old function calls. -* Enhancement: Slideshow: Add title and alt text to images. -* Enhancement: Subscription Form: Do not display the logged in user's email address by default. -* Enhancement: Top Posts Widget: Refactor to allow conditional loading of the css. -* Enhancement: Top Posts: Add `jetpack_top_posts_widget_count` filter to control number of displayed posts. -* Bug Fix: Change subscribe_text from `p` to `div` so that it can contain block-level elements. -* Bug Fix: Fonts: Change path to look for the svg in the right directory. -* Bug Fix: Increase CSS specificity for Contact Forms in widgets. -* Bug Fix: JSON API: Plugins Update: Make sure the plugin doesn't get deactivated. -* Bug Fix: Likes: Fixes issues where likes don't load, load master iframe after scripts are loaded. -* Bug Fix: Notes Module: Avoid a PHP Notice in cli scripts when the request doesn't contain a User-Agent header. -* Bug Fix: Nova Menu CPT: fix notice when we have no taxonomies. -* Bug Fix: Nova Menus: Use current instance to maintain object context. -* Bug Fix: Related Posts: Add filter for `_enabled_for_request()`. -* Bug Fix: Sharing: Prevent duplicate @ in shared Tweets. -* Bug Fix: Site Logo: `get_site_logo()` now properly returns the site logo ID when provided in the `$show` argument. -* Bug Fix: Site Logo: Correct evaluation of the Display Header Text in Customizer preview. - -= 3.2.1 = -Release Date: November 14th, 2014 - -* Enhancement: Updated translation files. -* Enhancement: JSON API: More object vars passed back to some queries. Documentation on http://developer.wordpress.com/ -* Bug Fix: JSON API: Pass back correct author in `me/posts` data. -* Bug Fix: JSON API: Don't check if a post is freshly pressed on remote Jetpack sites where the function doesn't exist. -* Bug Fix: Site Logo: Add backward-compatible template tags to match the standalone release. -* Bug Fix: Don't use __DIR__ -- it's 5.3+ only, and WordPress supports back to 5.2. -* Bug Fix: Retool how we remove the source styles when using the concatenated version. -* Bug Fix: Shortcodes: TED: Correct default language code from `eng` to `en`. -* Bug Fix: Gallery Widget: Add a default background color. -* Bug Fix: Subscription Notifications: Remove the label. -* Bug Fix: Sharing: enqueue Genericons on static front page as well if selected. - -= 3.2 = -Release Date: October 29, 2014 -Release Post: http://wp.me/p1moTy-181 - -* Enhancement: Speed Improvements (woohoo!). -* Enhancement: Add site icons: an avatar for your blog. -* Enhancement: Improvements to API endpoints. -* Enhancement: Add oEmbed sources (Twitter, SoundCloud, Instagram, DailyMotion, Vine). -* Enhancement: Add indicators to make it easier to see which modules are active. -* Enhancement: Improve debug tool. -* Enhancement: Add new 'Site Logos' code to theme tools, for themes that opt in to support it. -* Enhancement: Improved caching for related posts. -* Enhancement: Added "Remember Me" functionality to Single Sign On. -* Enhancement: Improved accessibility. -* Enhancement: Added additional filters to Widget Visibility. -* Bug Fix: Fixed PHP Notice errors for Likes, Widget Visibility. -* Bug Fix: Improvements to the testimonials CPT. -* Bug Fix: Improved RTL on VideoPress admin. -* Bug Fix: Removed Google+ Authorship module (discontinued by Google). -* Bug Fix: Fixed use of deprecated function in mobile theme. -* Bug Fix: Various fixes to Tiled Galleries. -* Bug Fix: Various fixes to Contact Form. -* Bug Fix: Various fixes to oEmbed. -* Bug Fix: Various fixes to Single Sign On. -* Bug Fix: Fixed styles in ShareDaddy. -* Bug Fix: Better match protocols (http/https) to the site. - - -= 3.1.1 = -Release Date: August 7, 2014 - -* Enhancement: Update translation files for strings that had been submitted/approved since release. -* Bug Fix: Social Links: Add a function check to better degrade if Publicize isn't around. -* Bug Fix: Open Graph: Add WordPress SEO back to the blacklist, until they update how they opt us out. -* Bug Fix: Asset Minification: Add another caveat ( empty $plugin ) to short out on. -* Bug Fix: Deprecated Hooks: Fixing our expectations where something that should be an array occasionally wasn't. -* Bug Fix: Custom CSS: Add extra whitelist rule for -o-keyframe rules. - -= 3.1 = -Release Date: July 31, 2014 -Release Post: http://wp.me/p1moTy-129 - -* Enhancement: New Custom Content Types module. -* Enhancement: New Jetpack Logo. -* Enhancement: New optional JSON API endpoints for viewing updates and managing plugins and themes. -* Enhancement: New Custom Post Type: Portfolio! -* Enhancement: Rearranged buttons on the modules modals for easier management. -* Enhancement: Jetpack Settings have improved keyboard accessibility. -* Enhancement: Improved RTL support for After the Deadline, Carousel, Contact Form, Comics CPT, Custom CSS, Omnisearch, Publicize, Related Posts, Slideshow short code, Tiled Gallery, Widget-Visibility and Widgets Gallery. -* Enhancement: Contact Form: Add an "Empty Spam" option. -* Enhancement: i18n: Change the priority of where plugin_textdomain is hooked so that the plugins can better translate Jetpack. -* Enhancement: Monitor: Displays how often the site is checked for downtime. -* Enhancement: Shortcode: Added Mixcloud shortcode and oEmbed support. -* Enhancement: Social Links: Improved handling of customizer hooks in non-admin context. -* Enhancement: Stats: The smiley image is gone by default. -* Enhancement: Stats: Added link to the configure page for stats so that the stats settings page is easier to find. -* Enhancement: Theme Tools: Added the responsive videos to theme tools so that themes can support responsive videos more easily. -* Update: Updated Genericons to version 3.1, new icons for website, ellipsis, foursquare, x-post, sitemap, hierarchy and paintbrush. -* Bug Fix: Contact Form: Prefix function to avoid conflicts with other plugins. -* Bug Fix: Custom CSS: Admin UI has a responsive layout. -* Bug Fix: Custom CSS: Custom $content_width value doesn't overwrite theme's $content_width. -* Bug Fix: Contact Form: Feedback link takes you to the form page. -* Bug Fix: Carousel: Confirms an avatar is returned by get_avatar before displaying. -* Bug Fix: Featured Content: Don't remove setting validation. -* Bug Fix: Infinite Scroll: Google Universal Analytics support added. -* Bug Fix: Multisite: Add message when updating multisite settings. -* Bug Fix: Photon: Photon will no longer upscale images larger than the original size. -* Bug Fix: Photon: Check that the image exists before rewriting the image URL to utilize Photon. -* Bug Fix: Sharing: Pinterest adds attribute to display share count. -* Bug Fix: Sharing: Respect an empty sharing title. -* Bug Fix: Sharing: Share buttons now appear in the bbPress forms. -* Bug Fix: Sharing: Support for multiple meta html tag og:image values. -* Bug Fix: Single Sign On: Logout allows override of forcing Single Sign On. -* Bug Fix: Single Sign On: Remove the lost password link on auto-forward logout. -* Bug Fix: Social Links: Do not use anonymous function for compatibility with PHP 5.2. -* Bug Fix: Tiled Galleries: Update jQuery mouseover caption effect to reduce flickering. -* Bug Fix: Widgets Visibility: Works better in the customizer admin view. - -= 3.0.2 = -Release Date: June 17, 2014 - -* Enhancement: General: Make module categories filter more visible when active. -* Enhancement: General: Updated translation files with more strings added since the last release. -* Enhancement: General: Allow deep-linking to the Contact Support form. -* Bug Fix: General: RTL Jetpack Admin UI looks better. -* Bug Fix: General: Fixed PHP warning when bulk deactivating modules. -* Bug Fix: General: Removed an unnecessary description. -* Bug Fix: General: Resolved an SSL error on Jetpack Admin UI. -* Bug Fix: General: Fix error comparing signatures when the WordPress installation is using site_url filters (applied mostly to WPEngine sites). -* Bug Fix: General: Resolved PHP strict error on the mobile menu. -* Bug Fix: General: Fix timing of conditional checks, so that calling developer mode via a plugin works again. -* Bug Fix: General: Main page categories tab now properly translates module names. -* Bug Fix: Related Posts: Fix a typo, the "more info" link now works. -* Bug Fix: Likes: Improve button styling. -* Bug Fix: Likes: Remove unused UI for Reblog settings on social settings page. -* Bug Fix: Contact Form: Updated to no longer use a deprecated Akismet function. -* Bug Fix: Contact Form: Sends email to the administrator that is not marked as spam again. -* Bug Fix: Open Graph: Resolved PHP warning on open graph gallery pages when the gallery is empty. - -= 3.0.1 = -Release Date: May 22, 2014 - -* Bug Fix: AtD: A wpcom-only function got synced by mistake and caused a few errors. Fixed. -* Bug Fix: Post By Email: Add static keyword to a function. -* Bug Fix: ShareDaddy: In the admin-side configuration of sharing links, we used a Path icon instead of Pinterest. Oops! -* Bug Fix: ShareDaddy: We inadvertently appended `via @jetpack` to some twitter shares. This is no longer the case. -* Bug Fix: Related Posts: Tidying up and relocation of the `resync` button formerly on the more info modal. -* Bug Fix: Infinite Scroll: Work better with core's MediaElement.js -* Bug Fix: Heartbeat: Undeclared variable fixed. - -= 3.0 = -Release Date: May 20, 2014 -Release Post: http://wp.me/p1moTy-Wi - -* New User Interface for managing modules and settings -* New Module: Verfication Tools -* Enhancement: New look for the Sharing module -* Enhancement: Multiple improvements on which Twitter handle a Twitter card will display -* Enhancement: Add option to hide Google+ Authorship banner while still receiving the benefits -* Enhancement: Many Infinite Scroll enhancements to improve performance -* Enhancement: Infinite Scroll will use your CPT's display name instead of "Older Posts" -* Enhancement: JSON API added /media/new endpoint -* Enhancement: Added filter to assign new default image for Open Graph tags -* Enhancement: New [jetpack-related-posts] shortcode to add Related Posts to page instead of default placement -* Enhancement: Added SSO option to turn off login form completely, to use WordPress.com login exclusively -* Enhancement: The [googlemaps] shortcode allows for Google Maps Engine -* Enhancement: YouTube shortcode allows HD playback -* Enhancement: Smoother, Faster Tiled Galleries! -* Enhancement: New languages! Use Jetpack in Irish, Fulah, and Tigrinya -* Bug Fix: Use your browser's Back and Forward buttons when naviagating a Carousel -* Bug Fix: Various Related Posts fixes and improvements for added flexibility -* Bug Fix: WordPress 3.9: Restores ability to edit Contact Forms -* Bug Fix: WordPress 3.9: Restores Gallery Widget compatability -* Bug Fix: Ensure Markdown is kept when Bulk Editing posts -* Bug Fix: Improved Jetpack's Multisite Network Admin page for networks with a large number of sites -* Bug Fix: Ensure Sharing settings persist when Bulk Editing a post -* Bug Fix: Various other shortcode improvements - -= 2.9.3 = -Release Date: April 10, 2014 -Release Post: http://wp.me/p1moTy-U2 - -* Important security update. CVE-2014-0173 - -= 2.9.2 = -Release Date: March 17, 2014 - -* Bug Fix: Publicize: When publishing from a mobile app or third-party client, Publicize now works again. - -= 2.9.1 = -Release Date: March 6, 2014 - -* Bug Fix: After the Deadline: Fix a Javascript glitch that could prevent publishing of posts. -* Bug Fix: SSO: Disable the implementation of an option that had been removed before release. This would have only been an issue if a site administrator had enabled the module during an early beta of 2.9. - -= 2.9 = -Release Date: February 26, 2014 -Release Post: http://wp.me/p1moTy-RN - -* Added Multisite network functionality -* New Module: Related Posts -* Enhancement: Single Sign On -* Enhancement: Mixcloud shortcode and oEmbed -* Enhancement: Gist shortcode and oEmbed -* Enhancement: Modify Facebook Like Box widget to support new Facebook parameters -* Enhancement: Rolled the Push Notifications module into the Notes module -* Enhancement: Update kses with Markdown -* Enhancement: Adding keyboard accessibility to sharing buttons config page -* Enhancement: Pull WordPress testing bits from the new official git mirror at WordPress.org -* Bug Fix: Widget Visibility -* Bug Fix: Revisions box in Custom CSS -* Bug Fix: Fix several bugs in the WordPress Posts Widget so that it correctly updates -* Bug Fix: Limit Login Attempts no longer generates false positives from xmlrpc. -* Bug Fix: Clear max_posts transient on theme switch. -* Bug Fix: Lower priority of sync to allow all CPTs to be registered. -* Bug Fix: Contact form fields emailed in correct order. - -* Other bugfixes and enhancements at https://github.com/Automattic/jetpack/commits/2.9 - -= 2.8 = -Release Date: January 31, 2014 -Release Post: http://wp.me/p1moTy-Pd - -* New Module: Markdown -* Module Update: Jetpack Monitor -* Enhancement: Infinite Scroll: Keep track of $current_day between requests so the_date() works well. -* Enhancement: Embeds: New filter to turn off embeds in comments. -* Enhancement: Contact Form: Add placeholder support. -* Enhancement: Widget: Gravatar Profile: Added filters to allow users to customize headings and fixed output of personal links. -* Enhancement: Facebook OG Tags: Add `published_time`, `modified_time`, and `author` if the post type supports it. -* Enhancement: Sharing: Display buttons on CPT archive pages. -* Enhancement: Sharing: Add `get_share_title` function and filter. -* Enhancement: Sharing: Add filter `sharing_display_link`. -* Enhancement: Twitter Timeline: Flesh out tweet limit option. -* Enhancement: Social Links: Add Google+ to the list of supported services. -* Enhancement: Stats: Improve dashboard styles in 3.8. -* Enhancement: Stats: No longer use Quantcast. -* Enhancement: Top Posts: Add `jetpack_top_posts_days` filter. -* Enhancement: AtD: Add TinyMCE 4 compatibility for its pending arrival in WordPress 3.9 -* Enhancement: Genericons: Update to v3.0.3 -* Enhancement: Tiled Galleries: Add alt attributes to images. -* Enhancement: Shortcode: YouTube: Accept protocol-relative URLs. -* Enhancement: Shortcode: Slideshow: Add white background option. -* Enhancement: Shortcode: YouTube: Add support for the two closed-caption arguments. -* Enhancement: Shortcode: Vimeo: Update the regex to support the new embed code. -* Enhancement: Shortcode: Google Maps: Update the regex to handle new format for embeds. -* Enhancement: Likes: Avoid a PHP Notice when $_POST['post_type'] is not set in meta_box_save. -* Enhancement: Smush images to save on file size. -* Enhancement: Publicize: Enable opt-in publicizing of custom post types. -* Bug Fix: Random Redirect: Further namespace to avoid conflicts. -* Bug Fix: Twitter Timeline: Resolve undefined index notice. -* Bug Fix: Featured Content: Add extra class_exists() check to be extra careful. -* Bug Fix: Facebook OG Tags: Change OG type of Home and Front Page to 'website' -* Bug Fix: Widget Visibility: Add support for old-style single use widgets. -* Bug Fix: Google Authorship: Support apostrophe in author names. -* Bug Fix: Media Extractor: Assorted graceful failure caveats. -* Bug Fix: Carousel: 'Link to None' bug fixed. -* Bug Fix: Embeds: Bandcamp: Switch escaping function for album and track IDs to handle (int)s greater than PHP_INT_MAX -* Bug Fix: Some plugins trying to catch brute-force attacks mistakenly flagged the Jetpack connection as one. - -= 2.7 = -Release Date: December 11, 2013 -Release Post: http://wp.me/p1moTy-Mk - -* Enhancement: Google+ Publicize -* Enhancement: Add Cloudup as an oEmbed provider -* Enhancement: Subscriptions: Add subscribe_field_id filter to allow updated ids when using multiple widgets -* Enhancement: Infinite Scroll: TwentyFourteen Support -* Bug Fix: Contact Form: Fix warning when form is called outside the loop -* Bug Fix: Featured Content: Moving Settings to Customizer, provide option to set default tag as fallback, specify all supported post-types rather than just additional ones. Description Updates -* Bug Fix: Featured Content: Compat with 'additional_post_types' theme support argument. Comment updates -* Bug Fix: Featured Content: Make sure $term is an object before we treat it as one -* Bug Fix: GlotPress: Merge with latest GlotPress -* Bug Fix: Infinite Scroll: prevent Undefined index notice that can cause IS to fail when user has WP_DEBUG set to true -* Bug Fix: Infinite Scroll: Improved compatibility with Carousel, Tiled Galleries, VideoPress, and the `[audio]` and `[video]` shortcodes -* Bug Fix: Likes: Stop manually including version.php and trust the global. Some whitespace fixes, and if it's an attachment, follow the post_status of the parent post -* Bug Fix: Mobile Theme: Display password field for Gallery format protected posts -* Bug Fix: Sharing: Add new translation width for share button, and Google Plus icons -* Bug Fix: Shortcodes: Support Ineternational Google domains for maps -* Bug Fix: Shortcodes: Facebook Embeds: Register alternate permalink.php URL for posts -* Bug Fix: Subscriptions: Moved inline styles from widget email input to separate css file -* Bug Fix: Theme Tools: Fix glitch where random-redirect.php also showed as a plugin being deleted if you were deleting Jetpack -* Bug Fix: Misc: Internationalization & RTL updates -* Bug Fix: Misc: Prevent collisions with 'Facebook Featured Image & OG Meta Tags' plugin - -= 2.6.1 = -Release Date: December 3, 2013 - -* Bug Fix: minor styling fix in pre- and post-MP6/3.8 UI changes. -* Bug Fix: Stats: spinner gif url fix when the user is viewing it over https. -* Bug Fix: Stats: Switch to esc_html from htmlspecialchars in error message -- better to be native -* Bug Fix: Media Extractor: some hosts don't compile unicode for preg_match_all, so we temporarily removed the block that depended on it. -* Bug Fix: Media Extractor: Add in some error handling for malformed URLs. -* Bug Fix: Twitter Cards: treat single-image galleries as a photo-type. -* Bug Fix: Update conflicting plugins for OG tags and Twitter Cards. -* Bug Fix: Correct max supported version number -- had been 3.6, update to 3.7.1 - -= 2.6 = -Release Date: November 28, 2013 -Release Post: http://wp.me/p1moTy-KE - -* Enhancement: WPCC / now called [SSO](http://jetpack.com/support/sso/): refactored. -* Enhancement: Monitor: new module which will notify you if your site goes down(http://jetpack.com/support/monitor/). -* Enhancement: Custom CSS: replace Ace editor with Codemirror. -* Enhancement: Widgets: new “Display Posts” widget. -* Enhancement: WP-CLI: add commands to disconnect a site and manage modules. -* Enhancement: Contact Form: new filters, `grunion_contact_form_field_html` and `grunion_should_send_email`. -* Enhancement: Custom Post Types: new restaurant post type. -* Enhancement: Genericons: update to version 3.0.2. -* Enhancement: Infinite Scroll: many improvements and fixes. -* Enhancement: Likes: performance improvements. -* Enhancement: MP6: Jetpack icons are now compatible with WordPress 3.8. -* Enhancement: Open Graph: better descriptions, fallback images, and media extraction from video posts. -* Enhancement: Publicize: new background token tests for connected publicize services and display problems on settings sharing and add new post. -* Enhancement: Shortcodes: updated Bandcamp shortcode to support the `tracklist` and `minimal` attributes, as well as more `artwork` attribute values. -* Enhancement: Shortlinks: add Custom Post Type support. -* Enhancement: Subscriptions: add more ways to customize the subscriptions widget. -* Enhancement: Twitter Cards: better media management and card type detection, and better handling of conflicts with other Twitter Cards plugins. -* Enhancement: better handling of conflicts with other plugins. -* Bug Fix: After the Deadline: add a typeof check for `tinyMCEPreInit.mceInit` to prevent js errors. -* Bug Fix: Carousel: speed improvements and several bugfixes. -* Bug Fix: Contact Form: remove nonce creating issues with caching plugins. -* Bug Fix: Custom Post Types: Testimonials: return if featured image is empty so it can be removed after it’s been set. -* Bug Fix: Featured Content: add additional post type support through the `additional_post_types` argument. -* Bug Fix: Google Authorship: support apostrophes in Google+ profiles. -* Bug Fix: Google Authorship: use a regexp Instead of using `mb_convert_encoding`, which doesn’t enjoy universal support. -* Bug Fix: Heartbeat: ensure that it never triggers more than once per week. -* Bug Fix: JSON API: add new `?meta=` parameter that allows you to expand the data found in the `meta->links` responses. -* Bug Fix: JSON API: add new `is_private` response to the sites endpoint and `global_ID` response to the reader and post endpoints. -* Bug Fix: Mobile Theme: allow small images to display inline. -* Bug Fix: Mobile Theme: fix fatal errors for missing `minileven_header` function. -* Bug Fix: Photon: fix errors when an image is not uploaded properly. -* Bug Fix: Shortcodes: improvements to Archives, Google+, Presentations, Vine and Youtube. -* Bug Fix: Tiled Galleries: improve display of panoramic images and fix errors when an image is not uploaded properly. - -= 2.5 = -Release Date: September 19, 2013 -Release Post: http://wp.me/p1moTy-xS - -* Enhancement: Connect your Google+ profile and WordPress site to prove authorship of posts. -* Enhancement: Improved sharing buttons display. -* Enhancement: Comment on your posts using Google+ to signin. -* Enhancement: Embed Google+ posts into your posts. -* Enhancement: Added event logging capabilities for debugging -* Enhancement: LaTeX is now available in dev mode -* Enhancement: Introduced gallery widget -* Enhancement: Added new module: VideoPress -* Enhancement: Updated identity crisis checker -* Enhancement: Tiled Gallery widget added -* Enhancement: Google +1 button changed to Google+ Share button, to avoid confusion -* Enhancement: Added check to ensure Google+ authorship accounts have disconnected properly -* Enhancement: Updated identity crisis checker -* Enhancement: Tiled Gallery widget added -* Enhancement: Google +1 button changed to Google+ Share button, to avoid confusion -* Enhancement: Added the ability to embed Facebook posts -* Bug Fix: Redirect issue with G+ authorship when WordPress is not in the root directory -* Enhancement: Better security if carousel to prevent self-XSS -* Enhancement: Better handling of cookies for subsites on multisite installs -* Bug Fix: Check for post in G+ authorship before accessing it - -= 2.4.2 = -Release Date: September 5, 2013 - -* Enhancement: Converted to module headers to detect Auto-Activating modules. -* Enhancement: WPCC: Added 'Close' link to deactivate WPCC in the admin nag. -* Enhancement: JSON API: Add User Nicename to the user data. -* Bug Fix: Contact Form: Stopped using a short tag. -* Bug Fix: Changed CSS selector to catch MP6 stylings. -* Bug Fix: Dropped __FILE__ references in class.jetpack.php in favor of JETPACK__PLUGIN_DIR constant, now code that deactivates the plugin from the connect nag works again. -* Bug Fix: Random Redirect: Add random-redirect to the plugins overriden list, in case someone is using Matt's Random Redirect plugin. -* Bug Fix: Tiled Gallery: Revert r757178 relating to tiled gallery defaults. -* Bug Fix: Return false, not zero, if $GLOBALS['content_width'] isn't defined. -* Bug Fix: WPCC: Don't call wp_login_url() in the constructor -- if someone is running a custom login page, that can break things if their plugin runs get_permalink as a filter before init. -* Bug Fix: Tiled Gallery: Add fallback if post_parent == 0 due to infinite_scroll_load_other_plugins_scripts. -* Bug Fix: Custom CSS: Set the ACE gutter z-index to 1. -* Bug Fix: Custom Post Types: Switch from wp_redirect() to wp_safe_redirect(). -* Bug Fix: Likes: Set overflow:hidden; on the likes adminbar item. -* Bug Fix: Mobile Theme: Migrate where/when the custom header stuff is included. -* Bug Fix: Slideshow Shortcode: Add a height of 410px. - -= 2.4.1 = -Release Date: September 4, 2013 - -* Enhancement: Don't auto-activate WPCC. - -= 2.4 = -Release Date: August 30, 2013 -Release Post: http://wp.me/p1moTy-wv - -* Enhancement: WordPress.com Connect (WPCC): New Module. -* Enhancement: Widget Visibility: New Module. -* Enhancement: Shortcode: Addition of new Twitter Timeline shortcode. -* Enhancement: Shortcode: Addition of new Presentation shortcode. -* Enhancement: Shortcode: Addition of new Vine shortcode. -* Enhancement: Custom Post Types: CPTs are available. -* Enhancement: Subscriptions: Add 'jetpack_is_post_mailable' filter. -* Enhancement: OpenGraph: Add Twitter Cards meta tags as well. -* Enhancement: Custom CSS: Update lessc and scssc preprocessors to 0.4.0 and 0.0.7 respectively. -* Enhancement: Omnisearch: Add Media results. -* Enhancement: Likes: Use a protocol-agnostic iframe, instead of forced HTTPS. -* Enhancement: Top Posts: Increase post limit. -* Enhancement: Publicize: Updated JS and UI. -* Enhancement: Photon: New filter to let site admins/owners enable photon for HTTPS urls. -* Enhancement: New jetpack_get_available_modules filter. -* Enhancement: Subscriptions: Antispam measures. -* Bug Fix: Add inline style to keep plugins/themes from inadvertently hiding the Connect box. -* Bug Fix: Custom CSS: Respect the new wp_revisions_to_keep filter. -* Bug Fix: Photon: Only hook jetpack_photon_url into the filter if the user has Photon active. -* Bug Fix: Heartbeat: Used wrong object, occasinally fatal-erroring out for the cron. -* Bug Fix: Add an empty debug.php file to the /modules/ folder, to solve some update issues where it never got deleted. - -= 2.3.5 = -Release Date: August 12, 2013 -Release Post: http://wp.me/p1moTy-vf - -* Enhancement: Added Path support to Publicize. - -= 2.3.4 = -Release Date: August 6, 2013 -Release Post: http://wp.me/p1moTy-uL - -* Bug Fix: Correct when output occurs with CSV export for feedback. -* Bug Fix: Tidy up the Heartbeat API. -* Enhancement: User Agent: Improve detecting of bots. -* Enhancement: Genericons: Make sure we're pulling the freshest version from genericons.com on each release. -* Enhancement: JSON API: Open up replies/new endpoints so that users can comment on blogs that are not in their access token. -* Enhancement: Photon: Apply to `get_post_gallery()` function as well. -* Enhancement: Tiled Galleries: Add a default bottom margin to be more robust out of the box. -* Translations: Adding in fresher translation files. -* Deprecation: Removing the retinization code for 3.4, as it was included in WordPress trunk from 3.5 onwards. - -= 2.3.3 = -Release Date: July 26, 2013 -Release Post: http://wp.me/p1moTy-uv - -* Bug Fix: We were inadvertently overwriting cron schedules with our Jetpack heartbeat. This should now be fixed. -* Enhancement: New Facebook Sharing icons. -* Enhancement: Minor update to the Minileven stylesheet. - -= 2.3.2 = -Release Date: July 25, 2013 -Release Post: http://wp.me/p1moTy-uv - -* Bug Fix: Fixed an issue where Facebook Pages were not available when connecting a Publicize account. -* Bug Fix: For some web hosts, fixed an issue where 'Jetpack ID' error would occur consistently on connecting to WordPress.com. -* Enhancement: Adding some new stats and heartbeat checking to Jetpack. - -= 2.3.1 = -Release Date: July 2, 2013 -Release Post: http://wp.me/p1moTy-t9 - -* Enhancement: Social Links: Retooling the class for better consistency and performance behind the scenes. -* Enhancement: Omnisearch: Make it easier to search Custom Post Types. No longer need to extend the class, if all you want is a basic display. Just call `new Jetpack_Omnisearch_Posts( 'cpt' );` -* Enhancement: Sharing Buttons: LinkedIn: Use the official button's sharing link on the Jetpack implementation for a more consistent sharing experience and produce better results on LinkedIn's end. -* Enhancement: Debug / Connection: Better logic in determining whether the server can use SSL to connect to WPCOM servers. -* Enhancement: Sharing: Twitter: Calculate the size of the Tweet based on the short URL rather than the full URL size. -* Enhancement: Debug: More readable and understandable messages. -* Enhancement: Likes: Including some MP6 styles. -* Enhancement: Comments: Add new core classes to comment form. See http://core.trac.wordpress.org/changeset/24525 -* Bug Fix: Omnisearch: Don't load everything initially, run the providers off admin_init, and then issue an action for folks to hook into. -* Bug Fix: Omnisearch: Modify some child class functions to match the parent's parameters and avoid strict notices in newer versions of PHP. -* Bug Fix: Omnisearch: Hide the search form in the module description if the current user can't use it. -* Bug Fix: Comment Form: Use edit_pages, not edit_page (fixes glitch in previous beta, never publicly released). -* Bug Fix: Twitter Timeline Widget: Additional testing of values and casting to default if they are nonconforming. -* Bug Fix: Sharing: Pinterest: Make the button wider if there's a count to avoid overlapping with others. -* Bug Fix: Post By Email: Change configuration_redirect to static. -* Bug Fix: Likes: Don't call configuration_redirect as a static, do it as a method. -* Bug Fix: Add some further security measures to module activation. - -= 2.3 = -Release Date: June 19, 2013 -Release Post: http://wp.me/p1moTy-rX - -* Enhancement: Omnisearch: Search once, get results from everything! Omnisearch is a single search box that lets you search many different things -* Enhancement: Debugger: this module helps you debug connection issues right from your dashboard, and contact the Jetpack support team if needed -* Enhancement: Social Links: this module is a canonical source, based on Publicize, that themes can use to let users specify where social icons should link to -* Enhancement: It’s now easier to find out if a module is active or note, thanks to the new Jetpack::is_module_active() -* Enhancement: Contact Form: You are now able to customize the submit button text thanks to the submit_button_text parameter -* Enhancement: Comments: We've added a filter to let users customize the Comment Reply label, and users can now also customize the prompt on the comment form again. -* Enhancement: Mobile Theme: Add genericons.css and registering it so it’s easily accessible to other modules that may want it -* Enhancement: Tiled Galleries: You can now customize the captions, thanks to the jetpack_slideshow_slide_caption filter -* Enhancement: Widgets: Twitter Timeline: Add the noscrollbar option -* Enhancement: Widgets: Facebook Like Box Widget: add a show_border attribute -* Enhancement: Widgets: FB Like Box: let Jetpack users override the iframe background color set in an inline style attribute by using the jetpack_fb_likebox_bg filter -* Bug Fix: Carousel: Fix a bug where double-clicking a gallery thumbnail broke the carousel functionality -* Bug Fix: Comments: Change “must-log-in” to class from ID -* Bug Fix: Contact Form: Make the Add Contact Form link a button, ala Add Media in core -* Bug Fix: Contact Form: Fix encoding of field labels -* Bug Fix: Contact Form: Remove references to missing images -* Bug Fix: Fix 2 XSS vulnerabilities -* Bug Fix: JSON API: Minor fixes for bbPress compatibility -* Bug Fix: JSON API: Fix metadata bugs -* Bug Fix: JSON API: Add a new hook that is fired when a post is posted using the API -* Bug Fix: JSON API: Prefork/REST: update path normalizer to accept versions other than 1 -* Bug Fix: JSON API: Remove extra parenthesis in CSS -* Bug Fix: Custom CSS: Move content width filters higher up so that they’re active for all users, not just logged-in admins. -* Bug Fix: Custom CSS: All CSS properties that accept images as values need to be allowed to be declared multiple times so that cross-browser gradients work -* Bug Fix: Infinite Scroll: Allow themes to define a custom function to render the IS footer -* Bug Fix: Infinite Scroll: Fix up Twenty Thirteen styles for RTL and small viewports. -* Bug Fix: Likes: Fix ‘Call to undefined function’ -* Bug Fix: Likes: Add scrolling no to iframe to make sure that like button in admin bar does not show scrollbars -* Bug Fix: Likes: Remove setInterval( JetpackLikesWidgetQueueHandler, 250 ) call that was causing heavy CPU load -* Bug Fix: Mobile Theme: Remove unused variable & function call -* Bug Fix: Publicize: Fix LinkedIn profile URL generation -* Bug Fix: Publicize: Better refresh handling for services such as LinkedIn and Facebook -* Bug Fix: Shortcodes: Audio shortcode: Treat src as element 0. Fixes audio shortcodes created by wp_embed_register_handler when an audio url is on a line by itself -* Bug Fix: Bandcamp: Updates to the Bandcamp shortcode -* Bug Fix: Stats: Fix missing function get_editable_roles on non-admin page loads -* Bug Fix: Widgets: Twitter Timeline: Fix HTML links in admin; set default values for width/height; change some of the sanitization functions -* Bug Fix: Widgets: Top Posts Widget: Exclude attachments -* Bug Fix: Widgets: Top Posts Widget: fix data validation for number of posts -* Bug Fix: Fix PHP warnings non-static method called dynamically -* Bug Fix: Fixed an issue in image extraction from HTML content -* Bug Fix: Open Graph: Change default minimum size for og:image too 200×200 -* Note: The old Twitter widget was removed in favour of Twitter Timeline widget -* Note: Add is_module_active() to make it easier to detect what is and what isn’t -* Note: Compressing images via lossless methods -* Note: Tidying up jetpack’s CSS -* Note: Set the max DB version for our retina overrides that were meant to stop for WordPress 3.5 -* Note: Updating spin.js to the current version, and shifting to the canonical jquery.spin.js library -* Note: Adding Jetpack_Options class, and abstracting out options functions to it - -= 2.2.5 = -Release Date: May 1, 2013 -Release Post: http://wp.me/p1moTy-p8 - -* Enhancement: Stats: Counting of registered users' views can now be enabled for specific roles -* Bug Fix: Security tightening for metadata support in the REST API -* Bug Fix: Update the method for checking Twitter Timeline widget_id and update coding standards -* Bug Fix: Custom CSS: Allow the content width setting to be larger than the theme's content width -* Bug Fix: Custom CSS: Fix possible missing argument warning. - -= 2.2.4 = -Release Date: April 26, 2013 -Release Post: http://wp.me/p1moTy-oU - -* Bug Fix: JSON API compat file include was not assigning a variable correctly, thus throwing errors. This has been resolved. - -= 2.2.3 = -Release Date: April 26, 2013 -Release Post: http://wp.me/p1moTy-oR - -* Enhancement: Comments - Add the reply-title H3 to the comment form so that themes or user CSS can style it -* Enhancement: Custom CSS - Support for the CSS @viewport -* Enhancement: JSON API - Support for i_like, is_following, and is_reblogged -* Enhancement: JSON API: Custom Post Type Support -* Enhancement: JSON API: Meta Data Support -* Enhancement: JSON API: Bundled Support for bbPress -* Enhancement: JSON API: Additions of following, reblog, and like status for post endpoints. -* Enhancement: Shortcodes - Add Bandcamp shortcode -* Enhancement: Tiled Galleries - Add code to get blog_id -* Bug Fix: Carousel - Support relative image paths incase a plugin is filtering attachment URLs to be relative instead of absolute -* Bug Fix: Carousel - Add likes widget to images / Respect comment settings for name/email -* Bug Fix: Carousel - Make name and email optional if the setting in the admin area says they are -* Bug Fix: Contact Form - Bug fixes, including a fix for WP-CLI -* Bug Fix: Contact Form - Remove deprecated .live calls, delegate lazily to jQuery(document) since it's all in an iframe modal -* Bug Fix: Contact Form - RTL styles -* Bug Fix: Contact Form - Better handle MP6 icons -* Bug Fix: Custom CSS - array_shift() took a variable by reference, so avoid passing it the result of a function -* Bug Fix: Custom CSS - Allow case-insensitive CSS properties (ref) -* Bug Fix: Infinite Scroll - Maintain main query's `post__not_in` values when querying posts for IS -* Bug Fix: Infinite Scroll - Ensure that IS's `pre_get_posts` method isn't applied in the admin. Also fixes an incorrect use of `add_filter()` where `add_action()` was meant. Fixes #1696-plugins -* Bug Fix: Infinite Scroll - CSS update - IS footer was too large in Firefox -* Bug Fix: Infinite Scroll - Add bundled support for Twenty Thirteen default theme -* Bug Fix: Infinite Scroll - Include posts table's prefix when modifying the SQL WordPress generates to retrieve posts for Infinite Scroll -* Bug Fix: JSON API - Use wp_set_comment_status to change the comment status, to make sure actions are run where needed -* Bug Fix: Likes - Update style and logic for matching id's -* Bug Fix: Mobile Theme - Ensure that minileven_actual_current_theme() is child-theme compatible + other updates -* Bug Fix: Mobile Theme - Update method for finding currently active theme. -* Bug Fix: Notifications - Remove the postmessage.js enqueue since this feature solely supports native postMessage -* Bug Fix: Notifications - Clean up script enqueues and use core versions of underscore and backbone on wpcom as fallbacks -* Bug Fix: Notifications - Enqueue v2 scripts and style -* Bug Fix: Notifications - Prefix module-specific scripts and style to prevent collision -* Bug Fix: Notifications - Include lang and dir attributes on #wpnt-notes-panel so the notifications iframe can use these to display correctly -* Bug Fix: Open Graph: Use the profile OG type instead of author. Add tags for first/last names -* Bug Fix: Publicize - Remove the Yahoo! service because they stopped supporting that API entirely -* Bug Fix: Publicize - fix fatal errors caused by using a method on a non-object. Props @ipstenu -* Bug Fix: Sharing - Adding 2x graphics for Pocket sharing service -* Bug Fix: Sharing - Bug fixes, and a new filter -* Bug Fix: Shortcodes - Audio: make sure that the Jetpack audion shortcode does not override the 3.6 core audio shortcode. Also, we need to filter the old Jetpack-style shortcode to properly set the params for the Core audio shortcode. -* Bug Fix: Shortcodes - Audio: Re-enable the flash player -* Bug Fix: Shortcodes - Slideshow: RTL styling update -* Bug Fix: Tiled Galleries - Fix IE8 display bug where it doesn't honor inline CSS for width on images -* Bug Fix: Tiled Galleries - Remove depreacted hover call, use mouseenter mouseleave instead -* Enhancement: Twitter Timeline Widget: New JavaScript based widget. Old one will discontinue May 7th. - -= 2.2.2 = -Release Date: April 5, 2013 - -* Enhancement: Mobile Theme: Add controls for custom CSS. -* Enhancement: Sharing: Add Pocket to the available services. -* Bug Fix: Custom CSS: Update the method for generating content width setting. -* Bug Fix: JSON API: Security updates. -* Bug Fix: Likes: Add settings for email notifications and misc style updates. -* Bug Fix: Notifications: Add the post types to sync after init. -* Bug Fix: Publicize: RTL styling. -* Bug Fix: Shortcodes: security fixes and function prefixing. -* Bug Fix: Widgets: Update wording on the Top Posts widget for clarity. -* Bug Fix: Jetpack Post Images security fixes. - -= 2.2.1 = -Release Date: March 28, 2013 -Release Post: http://wp.me/p1moTy-ob - -* Enhancement: Development Mode: Define the `JETPACK_DEV_DEBUG` constant to `true` to enable an offline mode for localhost development. Only modules that don't require a WordPress.com connection can be enabled in this mode. -* Enhancement: Likes: Added the number of likes to the wp-admin/edit.php screens. -* Enhancement: Mobile Theme - design refresh -* Enhancement: Shortcodes - Add a filter to the shortcode loading section so that a plugin can override what Jetpack loads for shortcodes -* Enhancement: Widgets - Filter Jetpack's widgets so that a plugin can control which widgets get loaded -* Bug Fix: Comments - Add in a wrapper div with id='commentform' -* Bug Fix: Contact Form - Added date field with datepicker -* Bug Fix: Contact Form - Allowed non-text widgets to use contact forms by running their output through the widget_text filter -* Bug Fix: Custom CSS - Allowing color values to be defined multiple times -* Bug Fix: Custom CSS - Dynamically loading the correct CSS/LESS/SCSS mode for the CSS editor if the user changes the preprocessor -* Bug Fix: Custom CSS - Using the unminified worker CSS -* Bug Fix: Custom CSS - Added rule: reminder about using .custom-background on body selector -* Bug Fix: Custom CSS - Modified rule: Removed portion of overqualification rule that deems 'a.foo' overqualified if there are no other 'a' rules -* Bug Fix: Custom CSS - Ensuring that the editor and the textarea behind it are using the same font so that the cursor appears in the correct location -* Bug Fix: Custom CSS - Fix a bug that caused some sites to always ignore the base theme's CSS when in preview mode -* Bug Fix: Custom CSS - Run stripslashes() before passing CSS to save() -* Bug Fix: Custom CSS - Moving inline CSS and JavaScript into external files -* Bug Fix: Infinite Scroll - Use the `is_main_query()` function and query method -* Bug Fix: Infinite Scroll - Remove unused styles and an unnecessary margin setting -* Bug Fix: Infinite Scroll - Allow the query used with IS to be filtered, so IS can be applied to a new query within a page template -* Bug Fix: JSON API - Catch the 'User cannot view password protected post' error from can_view_post and bypass it for likes actions if the user has the password entered -* Bug Fix: Likes - Bump cache buster, Don't show likes for password protected posts -* Bug Fix: Notifications - Remove a redundant span closing tag -* Bug Fix: Photon - If an image is already served from Photon but the anchor tag that surrounds it hasn't had its `href` value rewritten to use Photon, do so. Accounts for WP galleries whose individual items are linked to the original image files -* Bug Fix: Publicize - Allows GLOBAL_CAP to be filtered, Adds an AYS to connection deletion, UI improvement for MP6 (and in general) -* Bug Fix: Sharedaddy - Fire the sharing redirect earlier for increased plugin compatibility -* Bug Fix: Stats - Move the display:none CSS output to wp_head so it gets written inside the HEAD tag if the option to hide the stats smilie is active -* Bug Fix: Tiled Galleries - A more descriptive name for the default gallery type -* Bug Fix: Tiled Galleries - Hide the Columns setting for gallery types that don't support it -* Bug Fix: Run the admin_menu action late so that plugins hooking into it get a chance to run -* Bug Fix: Prophylactic strict equality check - -= 2.2 = -Release Date: February 26, 2013 -Release Post: http://wp.me/p1moTy-ns - -* Enhancement: Likes: Allow your readers to show their appreciation of your posts. -* Enhancement: Shortcodes: SoundCloud: Update to version 2.3 of the SoundCloud plugin (HTML5 default player, various fixes). -* Enhancement: Shortcodes: Subscriptions: Add a shortcode to enable placement of a subscription signup form in a post or page. -* Enhancement: Sharedaddy: Allow selecting multiple images from a post using the Pinterest share button. -* Enhancement: Contact Form: Allow feedbacks to be marked spam in bulk. -* Enhancement: Widgets: Readmill Widget: Give your visitors a link to send your book to their Readmill library. -* Note: Notifications: Discontinue support for Internet Explorer 7 and below. -* Bug Fix: JSON API: Fix authorization problems that some users were experiencing. -* Bug Fix: JSON API: Sticky posts were not being sorted correctly in /posts requests. -* Bug Fix: Stats: sync stats_options so server has roles array needed for view_stats cap check. -* Bug Fix: Infinite Scroll: Display improvements. -* Bug Fix: Infinite Scroll: WordPress compatibility fixes. -* Bug Fix: Photon: Only rewrite iamge urls if the URL is compatible with Photon. -* Bug Fix: Photon: Account for registered image sizes with one or more dimesions set to zero. -* Bug Fix: Subscriptions: Make HTML markup more valid. -* Bug Fix: Subscriptions: Fixed notices displayed in debug mode. -* Bug Fix: Custom CSS: CSS warnings and errors should now work in environments where JavaScript is concatenated or otherwise modified before being served. -* Bug Fix: Hovercards: WordPress compatibility fixes. -* Bug Fix: Improved image handling for the Sharing and Publicize modules. -* Bug Fix: Carousel: Display and Scrollbar fixes. -* Bug Fix: Tiled Galleries: Restrict images in tiled galleries from being set larger than their containers. -* Bug Fix: Widgets: Gravatar Profile: CSS fixes. -* Bug Fix: Publicize: Strip HTML comments from the data we send to the third party services. -* Bug Fix: Notifications: Dropped support for IE7 and below in the notifications menu. -* Bug Fix: Custom CSS Editor: Allow custom themes to save CSS more easily. -* Bug Fix: Infinite Scroll: Waits until the DOM is ready before loading the scrolling code. -* Bug Fix: Mobile Theme: If the user has disabled the custom header text color, show the default black header text color. -* Bug Fix: Mobile Theme: Fix for the "View Full Site" link. -* Bug Fix: Mobile Theme: Use a filter to modify the output of wp_title(). -* Bug Fix: Publicize: Twitter: Re-enable character count turning red when more than 140 characters are typed. - -= 2.1.2 = -Release Date: February 5, 2013 - -* Enhancement: Infinite Scroll: Introduce filters for Infinite Scroll. -* Enhancement: Shortcodes: TED shortcode. -* Bug Fix: Carousel: Make sure to use large image sizes. -* Bug Fix: Carousel: Clicking the back button in your browser after exiting a carousel gallery brings you back to the gallery. -* Bug Fix: Carousel: Fix a scrollbar issue. -* Bug Fix: Comments: Move the get_avatar() function out of the base class. -* Bug Fix: Contact Form: Prevent the form from displaying i18n characters. -* Bug Fix: Contact Form: Remove the !important CSS rule. -* Bug Fix: Infinite Scroll: Main query arguments are not respected when using default permalink. -* Bug Fix: JSON API: Trap 'wp_die' for new comments and image uploads. -* Bug Fix: JSON API: Use a better array key for the user_ID. -* Bug Fix: JSON API: Make the class instantiable only once, but multi-use. -* Bug Fix: JSON API: Fix lookup of pages by page slug. -* Bug Fix: JSON API: Updates for post likes. -* Bug Fix: Mobile Theme: Remove Android download link for BB10 and Playbook. -* Bug Fix: Open Graph: Stop using Loop functions to get post data for meta tags. -* Bug Fix: Photon: Suppress and check for warnings when pasing_url and using it. -* Bug Fix: Photon: Ensure full image size can be used. -* Bug Fix: Photon: Resolve Photon / YouTube embed conflict. -* Bug Fix: Photon: Fix dimension parsing from URLs. -* Bug Fix: Photon: Make sure that width/height atts are greater than zero. -* Bug Fix: Sharedaddy: Layout fixes for share buttons. -* Bug Fix: Sharedaddy: Always send Facebook a language locale. -* Bug Fix: Sharedaddy: Don't look up share counts for empty URLs. -* Bug Fix: Shortcodes: Ensure that images don't overflow their containers in the slideshow shortcode. -* Bug Fix: Shortcodes: only enqueue jquery if archive supports Infinite Scroll in the Audio Shortcode. -* Bug Fix: Tiled Galleries: Use a more specific class for gallery item size to avoid conflicts. -* Bug Fix: Tiled Galleries: Fixing scrolling issue when tapping on a Tiled Gallery on Android. -* Bug Fix: Widgets: Gravatar profile widget typo. -* Bug Fix: Widgets: Add (Jetpack) to widget titles. -* Bug Fix: Widgets: Twitter wasn't wrapping links in the t.co shortener. -* Bug Fix: Widgets: Facebook Likebox updates to handling the language locale. -* Bug Fix: Widgets: Top Posts: Fixed a WP_DEBUG notice. -* Bug Fix: Widgets: Gravatar Profile Widget: transient names must be less than 45 characters long. -* Bug Fix: typo in delete_post_action function. -* Bug Fix: Load rendered LaTeX image on same protocol as its page. - - -= 2.1.1 = -Release Date: January 5, 2013 -Release Post: http://wp.me/p1moTy-ng - -* Bug Fix: Fix for an error appearing for blogs updating from Jetpack 1.9.2 or earlier to 2.1. - -= 2.1 = -Release Date: January 4, 2013 -Release Post: http://wp.me/p1moTy-m3 - -* Enhancement: Tiled Galleries: Show off your photos with cool mosaic galleries. -* Enhancement: Slideshow gallery type: Display any gallery as a slideshow. -* Enhancement: Custom CSS: Allow zoom property. -* Enhancement: Stats: Show WordPress.com subscribers in stats. -* Bug Fix: Fix errors shown after connecting Jetpack to WordPress.com. -* Bug Fix: Photon: Fix bug causing errors to be shown in some posts. -* Bug Fix: Photon: Convert all images in posts when Photon is active. -* Bug Fix: Infinite Scroll: Improved compatibility with the other modules. -* Bug Fix: Custom CSS: Updated editor to fix missing file errors. -* Bug Fix: Publicize: Don't show the Facebook profile option if this is a Page-only account. -* Bug Fix: Photon: A fix for photos appearing shrunken if they didn't load quickly enough. -* Bug Fix: Sharing: A compatibility fix for posts that only have partial featured image data. -* Bug Fix: Publicize/Sharing: For sites without a static homepage, don't set the OpenGraph url value to the first post permalink. -* Bug Fix: Mobile Theme: Better compatibility with the customizer on mobile devices. -* Bug Fix: Sharing: Don't show sharing options on front page if that option is turned off. -* Bug Fix: Contact Form: Fix PHP warning shown when adding a Contact Form in WordPress 3.5. -* Bug Fix: Photon: Handle images with relative paths. -* Bug Fix: Contact Form: Fix compatibility with the Shortcode Embeds module. - - -= 2.0.4 = -Release Date: December 14, 2012 -Release Post: http://wp.me/p1moTy-lT - -* Bug Fix: Open Graph: Correct a bug that prevents Jetpack from being activated if the SharePress plugin isn't installed. - -= 2.0.3 = -Release Date: December 14, 2012 -Release Post: http://wp.me/p1moTy-lJ - -* Enhancement: Infinite Scroll: support [VideoPress](http://wordpress.org/extend/plugins/video/) plugin. -* Enhancement: Photon: Apply to all images retrieved from the Media Library. -* Enhancement: Photon: Retina image support. -* Enhancement: Custom CSS: Refined editor interface. -* Enhancement: Custom CSS: Support [Sass](http://sass-lang.com/) and [LESS](http://lesscss.org/) with built-in preprocessors. -* Enhancement: Open Graph: Better checks for other plugins that may be loading Open Graph tags to prevent Jetpack from doubling meta tag output. -* Bug Fix: Infinite Scroll: Respect relative image dimensions. -* Bug Fix: Photon: Detect custom-cropped images and use those with Photon, rather than trying to use the original. -* Bug Fix: Custom CSS: Fix for bug preventing @import from working with url()-style URLs. - -= 2.0.2 = -Release Date: November 21, 2012 -Release Post: http://wp.me/p1moTy-lu - -* Bug Fix: Remove an erroneous PHP short open tag with the full tag to correct fatal errors under certain PHP configurations. - -= 2.0.1 = -Release Date: November 21, 2012 -Release Post: http://wp.me/p1moTy-lc - -* Enhancement: Photon: Support for the [Lazy Load](http://wordpress.org/extend/plugins/lazy-load/) plugin. -* Bug Fix: Photon: Fix warped images with un- or under-specified dimensions. -* Bug Fix: Photon: Fix warped images with pre-photonized URLs; don't try to photonize them twice. -* Bug Fix: Infinite Scroll: Check a child theme's parent theme for infinite scroll support. -* Bug Fix: Infinite Scroll: Correct a bug with archives that resulted in posts appearing on archives that they didn't belong on. -* Bug Fix: Publicize: Send the correct shortlink to Twitter (et al.) if your site uses a shortener other than wp.me. -* Bug Fix: Sharing: Improved theme compatibility for the Google+ button. -* Bug Fix: Notifications: Use locally-installed Javascript libraries if available. - -= 2.0 = -Release Date: November 8, 2012 -Release Post: http://wp.me/p1moTy-jg - -* Enhancement: Publicize: Connect your site to popular social networks and automatically share new posts with your friends. -* Enhancement: Post By Email: Publish posts to your blog directly from your personal email account. -* Enhancement: Photon: Images served through the global WordPress.com cloud. -* Enhancement: Infinite Scroll: Better/faster browsing by pulling the next set of posts into view automatically when the reader approaches the bottom of the page. -* Enhancement: Open Graph: Provides more detailed information about your posts to social networks. -* Enhancement: JSON API: New parameters for creating and viewing posts. -* Enhancement: Improved compatibility for the upcoming WordPress 3.5. -* Bug Fix: Sharing: When you set your sharing buttons to use icon, text, or icon + text mode, the Google+ button will display accordingly. -* Bug Fix: Gravatar Profile Widget: Allow basic HTML to be displayed. -* Bug Fix: Twitter Widget: Error handling fixes. -* Bug Fix: Sharing: Improved theme compatibility -* Bug Fix: JSON API: Fixed error when creating some posts in some versions of PHP. - -= 1.9.2 = -Release Date: October 29, 2012 - -* Bug Fix: Only sync options on upgrade once. - -= 1.9.1 = -Release Date: October 29, 2012 -Release Post: http://wp.me/p1moTy-iC - -* Enhancement: Notifications feature is enabled for logged-out users when the module is active & the toolbar is shown by another plugin. -* Bug Fix: Use proper CDN addresses to avoid SSL cert issues. -* Bug Fix: Prioritize syncing comments over deleting comments on WordPress.com. Fixes comment notifications marked as spam appearing to be trashed. - -= 1.9 = -Release Date: October 26, 2012 -Release Post: http://wp.me/p1moTy-hC - -* Enhancement: Notifications: Display Notifications in the toolbar and support reply/moderation of comment notifications. -* Enhancement: Mobile Push Notifications: Added support for mobile push notifications of new comments for users that linked their accounts to WordPress.com accounts. -* Enhancement: JSON API: Allows applications to send API requests via WordPress.com (see [the docs](http://developer.wordpress.com/docs/api/) ) -* Enhancement: Sync: Modules (that require the data) sync full Post/Comment to ensure consistent data on WP.com (eg Stats) -* Enhancement: Sync: Improve syncing of site options to WP.com -* Enhancement: Sync: Sync attachment parents to WP.com -* Enhancement: Sync: Add signing of WP.com user ids for Jetpack Comments -* Enhancement: Sync: Mark and obfuscate private posts. -* Enhancement: Privacy: Default disable enhanced-distribution and json-api modules if site appears to be private. -* Enhancement: Custom CSS: allow applying Custom CSS to mobile theme. -* Enhancement: Sharing: On HTTPS pageloads, load as much of the sharing embeds as possible from HTTPS URLs. -* Enhancement: Contact Form: Overhaul of the contact form code to fix incompatibilites with other plugins. -* Bug Fix: Only allow users with manage_options permission to enable/disable modules -* Bug Fix: Custom CSS: allow '/' in media query units; e.g. (-o-min-device-pixel-ratio: 3/2) -* Bug Fix: Custom CSS: leave comments alone in CSS when editing but minify on the frontend -* Bug Fix: Sharing: Keep "more" pane open so Google+ Button isn't obscured -* Bug Fix: Carousel: Make sure the original size is used, even when it is exceedingly large. -* Bug Fix: Exclude iPad from Twitter on iPhone mobile browsing -* Bug Fix: Sync: On .org user role changes synchronize the change to .com -* Bug Fix: Contact Form: Fix a bug where some web hosts would reject mail from the contact form due to email address spoofing. - -= 1.8.3 = -Release Date: October 23, 2012 - -* Bug Fix: Subscriptions: Fix a bug where subscriptions were not being sent from the blog. -* Bug Fix: Twitter: Fix a bug where the Twitter username was being saved as blank. -* Bug Fix: Fix a bug where Contact Form notification emails were not being sent. - -= 1.8.2 = -Release Date: October 4, 2012 -Release Post: http://wp.me/p1moTy-gI - -* Bug Fix: Subscriptions: Fix a bug where subscriptions were not sent for posts and comments written by some authors. -* Bug Fix: Widgets: Fix CSS that was uglifying some themes (like P2). -* Bug Fix: Widgets: Improve Top Posts and Pages styling. -* Bug Fix: Custom CSS: Make the default "Welcome" message translatable. -* Bug Fix: Fix Lithuanian translation. - -= 1.8.1 = -Release Date: September 28, 2012 -Release Post: http://wp.me/p1moTy-gx - -* Bug Fix: Stats: Fixed a bug preventing some users from viewing stats. -* Bug Fix: Mobile Theme: Fixed some disabled toolbar buttons. -* Bug Fix: Top Posts widget: Fixed a bug preventing the usage of the Top Posts widget. -* Bug Fix: Mobile Theme: Fixed a bug that broke some sites when the Subscriptions module was not enabled and the Mobile Theme module was enabled. -* Bug Fix: Mobile Theme: Made mobile app promos in the Mobile Theme footer opt-in. -* Bug Fix: Twitter Widget: A fix to prevent malware warnings. -* Bug Fix: Mobile Theme: Fixed a bug that caused errors for some users with custom header images. - -= 1.8 = -Release Date: September 27, 2012 -Release Post: http://wp.me/p1moTy-fV - -* Enhancement: Mobile Theme: Automatically serve a slimmed down version of your site to users on mobile devices. -* Enhancement: Multiuser: Allow multiple users to link their accounts to WordPress.com accounts. -* Enhancement: Custom CSS: Added support for object-fit, object-position, transition, and filter properties. -* Enhancement: Twitter Widget: Added Follow button -* Enhancement: Widgets: Added Top Posts and Pages widget -* Enhancement: Mobile Push Notifications: Added support for mobile push notifications on new comments. -* Enhancement: VideoPress: Shortcodes now support the HD option, for default HD playback. -* Bug Fix: Twitter Widget: Fixed tweet permalinks in the Twitter widget -* Bug Fix: Custom CSS: @import rules and external images are no longer stripped out of custom CSS -* Bug Fix: Custom CSS: Fixed warnings and notices displayed in debug mode -* Bug Fix: Sharing: Fixed double-encoding of image URLs -* Bug Fix: Sharing: Fix Google +1 button HTML validation issues (again :)) -* Bug Fix: Gravatar Profile Widget: Reduce size of header margins - -= 1.7 = -Release Date: August 23, 2012 -Release Post: http://wp.me/p1moTy-eq - -* Enhancement: CSS Editor: Customize your site's design without modifying your theme. -* Enhancement: Comments: Submit the comment within the iframe. No more full page load to jetpack.wordpress.com. -* Enhancement: Sharing: Share counts for Twitter, Facebook, LinkedIn -* Enhancement: Sharing: Improve styling -* Enhancement: Sharing: Add support for ReCaptcha -* Enhancement: Sharing: Better extensability through filters -* Enhancement: Widgets: Twitter: Attempt to reduce errors by storing a long lasting copy of the data. Thanks, kareldonk :) -* Regression Fix: Sharing: Properly store and display the sharing label option's default value. -* Bug Fix: Contact Form: remove worse-than-useless nonce. -* Bug Fix: Subscriptions: remove worse-than-useless nonce. -* Bug Fix: Sharing: Don't show sharing buttons twice on attachment pages. -* Bug Fix: Sharing: Increase width of Spanish Like button for Facebook. -* Bug Fix: Sharing: Use the correct URL to the throbber. -* Bug Fix: Stats: Fix notice about undefined variable $alt -* Bug Fix: Subscriptions: Make Subscriptions module obey the settings of the Settngs -> Discussion checkboxes for Follow Blog/Comments -* Bug Fix: Shortcodes: VideoPress: Compatibility with the latest version of VideoPress -* Bug Fix: Shortcodes: Audio: Include JS File for HTML5 audio player -* Bug Fix: Hovercards: Improve cache handling. -* Bug Fix: Widgets: Gravatar Profle: Correctly display service icons in edge cases. -* Bug Fix: Widgets: Gravatar Profle: Prevent ugly "flash" of too-large image when page first loads on some sites -* Bug Fix: Carousel: CSS Compatibility with more themes. - -= 1.6.1 = -Release Date: August 4, 2012 - -* Bug Fix: Prevent Fatal error under certain conditions in sharing module -* Bug Fix: Add cachebuster to sharing.css -* Bug Fix: Disable via for Twitter until more robust code is in place - -= 1.6 = -Release Date: August 2, 2012 -Release Post: http://wp.me/p1moTy-e0 - -* Enhancement: Carousel: Better image resolution selection based on available width/height. -* Enhancement: Carousel: Load image caption, metadata, comments, et alii when a slide is clicked to switch to instead of waiting. -* Enhancement: Carousel: Added a "Comment" button and handling to scroll to and focus on comment textarea. -* Enhancement: Widgets: Facebook Likebox now supports a height parameter and a better width parameter. -* Enhancement: Widgets: Better feedback when widgets are not set up properly. -* Enhancement: Shortcodes: Google Maps shortcode now supports percentages in the width. -* Enhancement: Shortcodes: Update Polldaddy shortcode for more efficient Javascript libraries. -* Enhancement: Shortcodes: Youtube shortcode now has playlist support. -* Enhancement: Add Gravatar Profile widget. -* Enhancement: Update Sharedaddy to latest version, including Pinterest support. -* Enhancement: Retinize Jetpack and much of WordPress. -* Bug Fix: Shortcodes: Fix Audio shortcode color parameter and rename encoding function. -* Bug Fix: Shortcodes: Don't output HTML 5 version of the Audio shortcode because of a bug with Google Reader. -* Bug Fix: Jetpack Comments: Don't overlead the addComments object if it doesn't exist. Fixes spacing issue with comment form. -* Bug Fix: Contact Form: If send_to_editor() exists, use it. Fixes an IE9 text area issue. - -= 1.5 = -Release Date: July 31, 2012 -Release Post: http://wp.me/p1moTy-d7 - -* Enhancement: Add Gallery Carousel feature -* Note: the Carousel module bundles http://fgnass.github.com/spin.js/ (MIT license) - -= 1.4.2 = -Release Date: June 20, 2012 - -* Bug Fix: Jetpack Comments: Add alternative Javascript event listener for Internet 8 users. -* Enhancement: Remove more PHP 4 backwards-compatible code (WordPress andJetpack only support PHP 5). -* Enhancement: Remove more WordPress 3.1 and under backwards-compatible code. - -= 1.4.1 = -Release Date: June 15, 2012 - -* Bug Fix: Jetpack Comments / Subscriptions: Add checkboxes and logic control for the Subscription checkboxes. - -= 1.4 = -Release Date: June 14, 2012 -Release Post: http://wp.me/p1moTy-cz - -* Enhancement: Add Jetpack Comments feature. -* Bug Fix: Sharing: Make the sharing_label translatable. -* Bug Fix: Sharing: Fixed the file type on the LinkedIn graphic. -* Bug Fix: Sharing: Fixes for the Faceboox Like button language locales. -* Bug Fix: Sharing: Updates for the "more" button when used with touch screen devices. -* Bug Fix: Sharing: Properly scope the More button so that multiple More buttons on a page behave properly. -* Bug Fix: Shortcodes: Update the YouTube and Audio shortcodes to better handle spaces in the URLs. -* Bug Fix: Shortcodes: Make the YouTube shortcode respect embed settings in Settings -> Media when appropriate. -* Bug Fix: Shortcodes: Removed the Slide.com shortcode; Slide.com no longer exists. -* Bug Fix: Shortcodes: Match both http and https links in the [googlemaps] shortcode. -* Bug Fix: After the Deadline: Code clean up and removal of inconsistencies. - -= 1.3.4 = -Release Date: May 24, 2012 - -* Bug Fix: Revert changes to the top level menu that are causing problems. - -= 1.3.3 = -Release Date: May 22, 2012 - -* Bug Fix: Fix notices caused by last update - -= 1.3.2 = -Release Date: May 22, 2012 - -* Bug Fix: Fix Jetpack menu so that Akismet and VaultPress submenus show up. - -= 1.3.1 = -Release Date: May 22, 2012 - -* Enhancement: Add a new widget, the Facebook Likebox -* Bug Fix: Sharing: Sharing buttons can now be used on custom post types. -* Bug Fix: Contact Forms: Make Contact Forms widget shortcode less aggressive about the shortcodes it converts. -* Bug Fix: Ensure contact forms are parsed correctly in text widgets. -* Bug Fix: Connection notices now only appear on the Dashboard and plugin page. -* Bug Fix: Connection notices are now dismissable if Jetpack is not network activated. -* Bug Fix: Subscriptions: Fix an issue that was causing errors with new BuddyPress forum posts. - -= 1.3 = -Release Date: April 25, 2012 -Release Post: http://wp.me/p1moTy-bq - -* Enhancement: Add Contact Forms feature. Formerly Grunion Contact Forms. -* Bug Fix: Tweak YouTube autoembedder to catch more YouTube URLs. -* Bug Fix: Correctly load the Sharing CSS files. - -= 1.2.4 = -Release Date: April 6, 2012 - -* Bug Fix: Fix rare bug with static front pages - -= 1.2.3 = -Release Date: April 5, 2012 -Release Post: http://wp.me/p1moTy-b4 - -* Enhancement: Twitter Widget: Expand t.co URLs -* Bug Fix: Various PHP Notices. -* Bug Fix: WordPress Deprecated `add_contextual_help()` notices -* Bug Fix: Don't display unimportant DB errors when processing Jetpack nonces -* Bug Fix: Correctly sync data during certain MultiSite cases. -* Bug Fix: Stats: Allow sparkline img to load even when there is a DB upgrade. -* Bug Fix: Stats: Replace "loading title" with post title regardless of type and status. -* Bug Fix: Stats: Avoid edge case infinite redirect for `show_on_front=page` sites where the `home_url()` conatins uppercase letters. -* Bug Fix: Subscriptions: Don't send subscriptions if the feature is turned off in Jetpack. -* Bug Fix: Subscriptions: Fix pagination of subscribers. -* Bug Fix: Subscriptions: Sync data about categories/tags as well to improve subscription emails. -* Bug Fix: Subscriptions: Better styling for the subscription success message. -* Bug Fix: Shortcodes: Support for multiple Google Maps in one post. Support for all Google Maps URLs. -* Bug Fix: Shortcodes: Improved support for youtu.be URLs -* Bug Fix: Shortcodes: Improved Vimeo embeds. -* Bug Fix: Sharing: Switch to the 20px version of Google's +1 button for consistency. -* Bug Fix: Sharing: Fix Google +1 button HTML validation issues. -* Bug Fix: Sharing: Disable sharing buttons during preview. -* Bug Fix: Spelling and Grammar: Properly handle proofreading settings. -* Bug Fix: Spelling and Grammar: Don't prevent post save when proofreading service is unavailable. - -= 1.2.2 = -Release Date: December 6, 2011 -Release Post: http://wp.me/p1moTy-ax - -* Bug Fix: Ensure expected modules get reactivated correctly during upgrade. -* Bug Fix: Don't send subscription request during spam comment submission. -* Bug Fix: Increased theme compatibility for subscriptions. -* Bug Fix: Remove reference to unused background image. - -= 1.2.1 = -Release Date: November 18, 2011 -Release Post: http://wp.me/p1moTy-9H - -* Bug Fix: Ensure Site Stats menu item is accessible. -* Bug Fix: Fixed errors displayed during some upgrades. -* Bug Fix: Fix inaccurate new modules "bubble" in menu for some upgrades. -* Bug Fix: Fix VaultPress detection. -* Bug Fix: Fix link to http://jetpack.com/faq/ - -= 1.2 = -Release Date: November 17, 2011 -Release Post: http://wp.me/p1moTy-8x - -* Enhancement: Add Subscriptions: Subscribe to site's posts and posts' comments. -* Enhancement: Add Google Maps shortcode. -* Enhancement: Add Image Widget. -* Enhancement: Add RSS Links Widget. -* Enhancement: Stats: More responsive stats dashboard. -* Enhancement: Shortcodes: Google Maps, VideoPress -* Enhancement: Sharing: Google+, LinkedIn -* Enhancement: Enhanced Distribution: Added Jetpack blogs to http://en.wordpress.com/firehose/ -* Bug Fix: Spelling and Grammar: WordPress 3.3 compatibility. -* Bug Fix: Translatable module names/descriptinos. -* Bug Fix: Correctly detect host's ability to make outgoing HTTPS requests. - -= 1.1.3 = -Release Date: July 19, 2011 -Release Post: http://wp.me/p1moTy-90 - -* Bug Fix: Increase compatibility with WordPress 3.2's new `wp_remote_request()` API. -* Bug Fix: Increase compatibility with Admin Bar. -* Bug Fix: Stats: Improved performance when creating new posts. -* Bug Fix: Twitter Widget: Fix PHP Notice. -* Bug Fix: Sharedaddy: Fix PHP Warning. -* Enhancement: AtD: Add spellcheck button to Distraction Free Writing screen. -* Translations: Added: Bosnian, Danish, German, Finnish, Galician, Croatian, Indonesian, Macedonian, Norwegian (Bokmål), Russian, Slovak, Serbian, Swedish -* Translations: Updated: Spanish, French, Italian, Japanese, Brazilian Portuguese, Portuguese - -= 1.1.2 = -Release Date: July 6, 2011 -Release Post: http://wp.me/p1moTy-8B - -* Bug Fix: Note, store, and keep fresh the time difference between the Jetpack site's host and the Jetpack servers at WordPress.com. Should fix all "timestamp is too old" errors. -* Bug Fix: Improve experience on hosts capable of making outgoing HTTPS requests but incapable of verifying SSL certificates. Fixes some "register_http_request_failed", "error setting certificate verify locations", and "error:14090086:lib(20):func(144):reason(134)" errors. -* Bug Fix: Better fallback when WordPress.com is experiencing problems. -* Bug Fix: It's Jetpack, not JetPack :) -* Bug Fix: Remove PHP Warnings/Notices. -* Bug Fix: AtD: JS based XSS bug. Props markjaquith. -* Bug Fix: AtD: Prevent stored configuration options from becoming corrupted. -* Bug Fix: Stats: Prevent missing old stats for some blogs. -* Bug Fix: Twitter Widget: Fix formatting of dates/times in PHP4. -* Bug Fix: Twitter Widget: Cache the response from Twitter to prevent "Twitter did not respond. Please wait a few minutes and refresh this page." errors. -* Enhancement: Slightly improved RTL experience. Jetpack 1.2 should include a much better fix. -* Enhancement: Sharedaddy: Improve localization for Facebook Like button. -* Enhancement: Gravatar Hovercards: Improved experience for Windows browsers. - -= 1.1.1 = -Release Date: March 19, 2011 -Release Post: http://wp.me/p1moTy-8i - -* Bug Fix: Improve experience on hosts capable of making outgoing HTTPS requests but incapable of verifying SSL certificates. Fixes most "Your Jetpack has a glitch. Connecting this site with WordPress.com is not possible. This usually means your site is not publicly accessible (localhost)." errors. -* Bug Fix: Sharedaddy: Fatal error under PHP4. Disable on PHP4 hosts. -* Bug Fix: Stats: Fatal error under PHP4. Rewrite to be PHP4 compatible. -* Bug Fix: Stats: Fatal error on some sites modifying/removing core WordPress user roles. Add sanity check. -* Bug Fix: Stats: Replace debug output with error message in dashboard widget. -* Bug Fix: Stats: Rework hook priorities so that stats views are always counted even if a plugin (such as Paginated Comments) bails early on template_redirect. -* Bug Fix: Identify the module that connot be activated to fatal error during single module activation. -* Bug Fix: `glob()` is not always available. Use `opendir()`, `readdir()`, `closedir()`. -* Bug Fix: Send permalink options to Stats Server for improved per post permalink calculation. -* Bug Fix: Do not hide Screen Options and Help links during Jetpack call to connect. -* Bug Fix: Improve readablitiy of text. -* Bug Fix: AtD: Correctly store/display options. -* Enhancement: Output more informative error messages. -* Enhancement: Improve CSS styling. -* Enhancement: Stats: Query all post types and statuses when getting posts for stats reports. -* Enhancement: Improve performance of LaTeX URLs be using cookieless CDN. - -= 1.1 = -Release Date: March 9, 2011 -Release post: http://wp.me/p1moTy-7R - -* Initial release +== Changelog == + += 4.0.4 = +Release date: June 20th, 2016 +Release Post: http://wp.me/p1moTy-3eT + +Security: + +* Post By Email: Added an additional layer of security to prevent unauthorized changes to Post By Email settings. +* Likes: Fixed an XSS vulnerability in the Likes module. +* REST API/Contact Form: We've eliminated unauthenticated access to Feedback posts. + +Feature Improvements: + +* Customizing Protect: We've increased Protect’s response time and added a new filter, `jetpack_protect_connect_timeout`, reducing the likelihood of seeing the fall back form. +* Connection Process: Your site url and icon are displayed on the Jetpack connection screens to help improve communication. +* Jetpack for Multisite: It’s now easier to manage your Jetpack connections on the network admin screen. +* Photon Responsive Image Improvements: We’re now auto-generating new scrset options, improving how images served from Photon are handled. +* Developing on Kinsta: A new constant has been added to improve developing with Jetpack on a staging environment hosted with Kinsta. + +Jetpack UI Improvements: + +* Better Access to Our Support Team: We wanted to make it easier for you to get help so we added a contact form in the admin that links directly to our Jetpack Support Team. + +Improved Compatibility: + +* We’ve stopped adding Open Graph Meta tags if you’re using the SEO Framework plugin. +* Having both GlotPress and Jetpack active at the same time was causing errors, we’ve eliminated them. + +Bug Fixes: + +* Fixed the handling of special characters like ampersands in Carousel Titles and Descriptions. +* When visitors tried to view a Carousel image with a hash in the URL, a JavaScript error would occur; we’ve fixed that. +* Jetpack Comment form fields now use the default language you’ve set for WordPress, previously the verbiage was always in English. +* Custom CSS wasn’t handling slashes and quotes properly; we’ve squashed that bug. +* There were some rare cases where PHP notices were popping up when a Contact Form was submitted. These instances have been identified and eliminated. +* We’ve replaced a bit of code with a Jetpack native function to fix a bug that was breaking things during an API request for available updates. +* We accidentally removed the ability for Open Graph to select images from slideshows, it’s up and running again. +* There was an issue where Open Graph meta tags weren’t being set when your homepage is a “Static Front Page”, it’s working again. +* In rare cases when developers were customizing Photon they were seeing a PHP notice when arguments were passed as a string rather than an array. This has been fixed. +* We’ve fixed an issue where Protect’s backup math form wasn’t showing on custom frontend login forms. +* When setting up WooCommerce you might have seen a Related Posts notice which didn’t belong. We’ve eliminated them. +* If you’ve been using our sharing tool with unofficial sharing buttons you might have noticed your sharing numbers were missing. They’re now back. +* In unique situations where special characters were used in sitemap stylesheets an error would occur; that has been remedied. +* We’ve fixed a problem with mismatching HTML tags in our Spelling and Grammar feature. +* We’ve ensured that the `jetpack_disable_twitter_cards` filter actually removes Twitter cards. +* We’ve fixed some JavaScript errors that would crop up if you were editing a custom-post-type post that didn’t support the core media editor — say that 10 times fast. +* We had some JavaScript errors when you were using the customizer to modify widgets. They are no longer with us. + += 4.0.3 = +Release date: May 26th, 2016 +Release Post: http://wp.me/p1moTy-3hm + +* Important security update. Please upgrade immediately. + += 4.0.2 = +Release date: April 21st, 2016 + +Bug Fix: + +* Addresses an issue where Jetpack 4.0 caused a fatal error on sites with specific configurations. + += 4.0 = +Release date: April 20th, 2016 +Release Post: http://wp.me/p1moTy-3dL + +Performance Enhancements: + +* Protect: the routine that verifies your site is protected from brute-force attacks got some love and is more efficient. +* Contact Forms: cleaning the database of spam form submission records is more efficient. + +Feature Improvements: + +* VideoPress: edit your VideoPress shortcode in the editor with a fancy new modal options window. +* Custom Content Types are now classier: a new CSS class on Testimonial featured images — has-testimonial-thumbnail — allows you to customize Jetpack custom post types as you see fit. +* Sharing: social icons are now placed under the "add to cart” singular product views in WooCommerce, making it easier for customers to share your products on social media. +* Theme Tools: search engines will now have an easier time knowing what page they are on, and how that page relates to the other pages in your site hierarchy with improved schema.org microdata for breadcrumbs. +* Widget Visibility: now you can select widgets and when to show or hide them right from custom post type single and archive views. + +Jetpack UI Improvements: + +* What’s in it for me? We’ve done a better job explaining the benefits of Jetpack and connecting it to WordPress.com. +* Shortcodes: handy links to shortcode documentation convey the types of media you can quickly and safely embed. +* Widgets: As of WordPress 4.5, Jetpack widgets now refresh in the customizer without making you refresh the entire page. Live previews, yes indeed. + +Bug Fixes: + +* Comments: we fixed a mistake where a comment subscription checkbox appeared on custom post types — despite the fact you couldn’t actually subscribe to those types of comments. Our bad. +* Contact Forms: we fixed a bug where the telephone field (which can only be added manually) rendered incorrectly — breaking some forms in the process. +* General: we blocked direct access to the Jetpack_IXR_Client class which caused fatal PHP errors in some server setups. +* Shortcodes: we removed the frameborder attribute in the YouTube embed code. It was deprecated in HTML 5. +* Unminified responsive-videos.min.js in order to address a false positive virus alert in ClamAV. Expect it to be re-minified in 4.0.3 once we resolve the issue with ClamAV. + += 3.9.6 = +Release date: March 31st, 2016 +Release Post: http://wp.me/p1moTy-3bz + +Bug fix: Shortcodes: fixed incorrect Vimeo embed logic. + += 3.9.5 = +Release date: March 31st, 2016 +Release Post: http://wp.me/p1moTy-3bz + +This release features several WordPress 4.5 compatibility changes that make several Jetpack features work properly in the Customizer view. Big thanks to @westonruter for contributing the code! + +Other enhancements and bug fixes: + +* Contact Form: no longer calling the datepicker method if it's not available. +* SSO: settings checkboxes now honor filters and constants that restrict certain sign-in modes. +* Shortcodes: fixed a problem with Gist fetching. +* Shortcodes: fixed invalid HTML5 markup in YouTube embed code. +* Shortcodes: made the Vimeo links work properly in case of multiple mixed uses in one post. + += 3.9.4 = +Release date: March 10th, 2016 +Release post: http://wp.me/p1moTy-396 + +Bug fix: Shortcodes: Addresses an issue with embedded Vimeo content + += 3.9.3 = +Release date: March 9th, 2016 +Release post: http://wp.me/p1moTy-396 + +Featured: + +* Site Logo now supports Custom Logo - a theme tool to be introduced in WordPress 4.5. + +Enhancements: + +* Carousel: Made the full size image URL use a Photon URL if enabled. +* Comments: Removed an unnecessary redirect by always connecting via HTTPS. +* General: Added new actions that fire before automatic updates. +* Infinite Scroll: Introduced a later filter for settings. +* Infinite Scroll: Removed code that is now redundant due to WordPress Core. +* Markdown: Removed deprecated markup from the output. +* Publicize: Improved handling of featured images in posts. +* Shortcodes: Added houzz.com support. +* Sitemaps: Added a language attribute to the news sitemap. +* Sitemaps: Improved the image retrieval mechanism for posts. +* Widgets: Added new filters in the Top Posts Widget code. +* Widgets: Cleaned up the CSS for the Subscription widget. + +Bug Fixes: + +* Comments: No longer reloading the page on clicking the reply button. +* Contact Forms: Fixed a fatal error on missing metadata. +* Contact Forms: Fixed message formatting for plaintext email clients. +* Shortcodes: Fixed dimensions of Vimeo embeds in certain cases. +* Shortcodes: Fixed warnings and allowed shorter style Vimeo embeds. +* Shortcodes: Removed alignment markup from feeds for YouTube embeds. +* Sitemaps: Made URLs display properly according to the permalink structure. +* Stats: Fixed non-XHTML-valid markup. +* Widgets: No longer showing errors when adding new instances of the Display Post Widget. + += 3.9.2 = +Release date: February 25th, 2016 +Release post: http://wp.me/p1moTy-2Ei + +Maintenance and Security Release + +Featured: + +* Beautiful Math: fix XSS vulnerability when parsing LaTeX markup within HTML elements. +* Contact Form: do not save private site credentials in post meta. Thanks to @visualdatasolutions. + +Enhancements: + +* Contact Info: Added two hooks for adding arbitrary information to the widget. +* Development: Added new possibilities for REST API debugging. +* Embeds: Added Codepen embeds support. +* Embeds: Added Sketchfab embeds support. +* I18n: Added support for translation packages for the Finnish language. +* Markdown: Added a filter to enable skipping processing of developer supplied patterns. +* Related Posts: Added a filter to change heading markup. +* Staging: Added a constant to force staging mode. +* Staging: Added a notice to make staging mode more obvious. +* Top Posts Widget: Added a new `[jetpack_top_posts_widget]` shortcode. + +Bug Fixes: + +* Custom Post Types: Nova: Fixed a JavaScript bug on adding multiple items. +* Embeds: Allowing embeds from Instagram with a www in an URL. +* General: Fixed untranslated module names on the Settings screen. +* General: Improved module descriptions and fixed misleading or broken links in descriptions. +* General: No more notices on module deprecation on older installations. +* General: Only showing one prompt to enable Photon when uploading several new images. +* Multisite: Fixed a problem with site lists for older WordPress installations. +* OpenGraph: Fixed a bug to properly fallback to a WordPress Site Icon image. +* Photon: Improve performance for images over a secure connection. +* Photon: No longer including links from data attributes. +* Publicize: Fixed problems for en_AU and en_CA locales with Facebook. +* Related Posts: Fixed a notice on certain requests. +* Site Logo: It's no longer possible to choose a non-image. +* Widget Visibility: No longer confusing page IDs and titles in certain cases. + += 3.9.1 = +Release date: January 21st, 2016 + +Bug Fixes: + +* General: Addresses a namespacing issue which was causing conflicts on some hosting providers. +* Sitemaps: Added MSM-Sitemap to the list of plugins which, if installed, will prevent Jetpack Sitemaps from being used + += 3.9 = +Release date: January 20th, 2016 +Release Post: http://wp.me/p1moTy-29R + +Featured: + +* New sharing button: let users share your content using Skype. +* New "Social Menu" theme tool that uses Genericons to display Social Links. +* Sitemap support for better search engine indexing. + +Enhancements: + +* Contact Form: Added a new filter that allows you to change the "Required" text. +* General: Hidden archived sites in multisite site list. +* General: Removed several function calls that would be deprecated in WordPress 4.5. +* Infinite Scroll: Added a new filter to check if Infinite Scroll has been triggered. +* Likes: Added a conditional to ensure WordPress 4.5 compatibility. +* Photon: Improved compatibility with responsive images feature added in WordPress 4.4. +* Photon: Now enabled by default on sites using HTTPS. +* REST API: Extended the ability to manage users from WordPress.com. +* REST API: Increased the performance of the plugin update endpoint. +* Responsive Videos: Centering videos when they are wrapped in a centered paragraph. +* Sharing: Added a new filter to customize the default OpenGraph description. +* Shortcodes: Added Wistia oEmbed support. +* Shortcodes: Bandcamp: Added support for new attributes for tracks approved by artists. +* Shortcodes: Improved Medium path format recognition. +* Slideshow: Improved compatibility with older IE versions. +* Staging: Improved staging environment detection. +* Widgets: Added "width" option to the Facebook Page widget. +* Widgets: Added size parameters to tags in Top Posts to avoid warnings. +* Widgets: Introduced major performance and stability improvements to the Display Posts Widget. +* Widgets: Refactored to remove deprecated code patterns. + +Bug Fixes: + +* AtD: Fixed replacing emojis with images in the text editor in Chrome. +* AtD: Made pre tags be excluded from spell-checking. +* CPT: Not registering Nova if it is already registered. +* Carousel: Fixed a bug where full size images were not always served by Photon. +* Carousel: Reverted a change that broke direct link to carousel image. +* Contact Form: Fixed a CSV export bug with multiple choice questions. +* Contact Form: Fixed notices when creating feedback entries without a contact form. +* General: Fixed a scrolling bug on modal window closing. +* Infinite Scroll: Disabled in the Customizer when previewing a non-active theme. +* Publicize: Fixed notices appearing with bbPress or BuddyPress installed. +* Publicize: Showing options only to users that can change them. +* Related Posts: Fixed incorrect URLs generated for posts. +* Responsive Videos: Fixed warnings in debug mode. +* Shortcodes: Bandcamp: Fixed a problem with large track IDs. +* Shortcodes: Fixed a problem with dynamic Gist embeds. +* Stats: Fixed dashboard widget resize problem. +* Widgets: Added a fallback to English US when a locale isn't supported by Facebook. +* Widgets: Fixed layout for Twenty Sixteen. + += 3.8.2 = +Release date: December 17th, 2015 +Release post: http://wp.me/p1moTy-26v + +Jetpack 3.8.2 is here to squash a few annoying bugs. + +Bug Fixes: + +* Photon: Fixed a bug where some custom thumbnail image sizes weren't being sized properly. +* Shortcodes: Fixed an incompatibility with how WordPress renders the YouTube shortcode. +* Shortcodes: Tightened up security in the Wufoo shortcode. +* Image Widget: Now shows the caption. +* Fixed typos in inline docs. +* Very minor fixes to: Carousel, Publicize, Google+, and Infinite Scroll. + += 3.8.1 = +Release date: December 1st, 2015 +Release post: http://wp.me/p1moTy-23V + +Jetpack 3.8.1 is here and is fully compatible with WordPress 4.4. + +Featured: + +* Photon + Responsive Images FTW. +* Fully compatible with Twenty Sixteen. +* More accessibility enhancements. +* Dropped some weight by optimizing Jetpack's plugin images. + +Enhancements: + +* Comments: filter to allow disabling comments per post type. + +Bug Fixes: + +* Carousel: Stop page from scrolling to top when Carousel is closed. +* Carousel: Browser compatibility fixes with older version of IE. +* Markdown: Fixed a bug that would strip markdown when saving in "Quick Edit" mode. +* Single Sign On: Fixed login always redirecting to the admin dashboard. +* Subscriptions: Filter to allow per-post emails fixed for use in themes. + += 3.8.0 = +Release date: November 4th, 2015 +Release post: http://wp.me/p1moTy-1VN + +We're happy to introduce Jetpack 3.8, which has significant contributions from the Jetpack community. Read more about it here: http://wp.me/p1moTy-1VN + +Feature enhancements: + +* New Google+ Badge Widget. Display your profile, page, or community Google+ badge. +* New twitch.tv shortcode embeds. Display a Twitch.tv stream in your posts. +* Accessibility enhancements. +* A handful of new filters to allow further customization of Jetpack. + +Other enhancements: + +* Carousel: Added support to retrieve image dimensions from an image url. +* Carousel: Simpler algorithm to detect shutter speeds. +* Contact Form: New "Checkbox with Multiple Items" field available in the Contact Form. +* Contact Form: Allow pre-filling form fields with URL parameters. +* Contact Form: Better styling of the emailed form responses. +* Performance: Replaced some custom-built functions with core's native functions. +* Related Posts: New filter to add post classes to post's container class. +* Sharing: New filter to choose if sharing meta box should be shown. +* Sharing: New filter to allow sharing button markup to be editable. +* Sharing: New filter to allow you to specify a custom Facebook app ID. +* Social Media Icons Widget: Added option for YouTube username as well as Channel ID. +* Social Media Icons Widget: Added Google+ icon. +* Social Media Icons Widget: New filter to allow you to add your own social media icons and links. +* Subscriptions: Better errors to your visitors if their subscription sign-up fails. +* Subscriptions: Removed "widget" class from Subs shortcode form. + + +Bug fixes: + +* Carousel: Fixed browser back/forward button behavior. +* Contact Form: Allow the email field to be set to empty when building form in post editor. +* Facebook Likebox Widget: Fixed an issue where some languages were not translating. +* Facebook Likebox Widget: Return a language when none found. +* General: Fixed some minor styling issues in the Jetpack admin areas. +* General: Add missing parameter to the_title filter call. +* General: Prevent scrolling of body when the Jetpack admin modals are opened. +* General: Update doc to reflect that Open Graph filter jetpack_enable_opengraph has been deprecated in favor of jetpack_enable_open_graph. +* Infinite Scroll: Fixed an error that sometimes occurred that would stop posts from loading. +* JSON API: Fixed some undefined notices when publishing a post with the API. +* Open Graph: Fixed bug where facebook description content was sometimes being polluted by a filter. +* Sharing: Use full SSL Pinterest url instead of protocol relative. +* Sharing: Fixed plus signs appearing in tweets shared from iOS. +* Shortcodes: Prefer HTTPS for video embeds to avoid mixed content warnings. +* Subscriptions Widget: Fix HTML Validation error. +* Theme Tools: Check oEmbeds for the presence of a video before adding the responsive videos filter. +* Tiled Galleries: Add image alt attribute if there is a title set. This was breaking some screen reader functionality. + += 3.7.2 = +Release date: September 29th, 2015 +Release Post: http://wp.me/p1moTy-1LB + +* Bug Fix: REST API: Fixed an error when saving drafts and publishing posts + += 3.7.1 = +Release date: September 28th, 2015 +Release Post: http://wp.me/p1moTy-1LB + +* Enhancement: General: Added inline documentation for various filters and functions +* Enhancement: General: Added custom capabilities for module management on multi-site installs +* Enhancement: General: Cleaned up old changelog entries from readme +* Enhancement: General: Cleaned up unused i18n textdomains +* Enhancement: General: Updated the new settings page to look better in various translations +* Enhancement: REST API: Added new endpoints to manage users +* Enhancement: Sharing: Updated the Google logo +* Bug Fix: Carousel: Page scroll no longer disappears after closing the carousel +* Bug Fix: Contact Form: Fields are sent and displayed in the correct order +* Bug Fix: Contact Form: No longer showing a notice on AJAX actions in feedback lists +* Bug Fix: Contact Form: Made using more than two notification emails possible +* Bug Fix: Contact Form: Mitigate a potential stored XSS vulnerability. Thanks to Marc-Alexandre Montpas (Sucuri) +* Bug Fix: General: Mitigate a potential information disclosure. Thanks to Jaime Delgado Horna +* Bug Fix: General: Fixed a locale error in the notifications popout +* Bug Fix: General: Fixed a possible fatal error in the client area +* Bug Fix: General: Fixed compatibility issues with certain use cases +* Bug Fix: General: Disabled connection warnings for multisites with domain mapping +* Bug Fix: General: Updated translations for correct link display in admin notices +* Bug Fix: REST API: Fixed a fatal error in one of the endpoints +* Bug Fix: Sharing: Fixed OpenGraph tags for Instagram embeds +* Bug Fix: Sharing: Fixed compatibility issues with bbPress +* Bug Fix: Widget Visibility: Fixed a fatal error in case of a missing tag + += 3.7.0 = +Release date: September 9th, 2015 +Release Post: http://wp.me/p1moTy-1JB + +Feature Enhancements: + +* New admin page interface to easily configure Jetpack +* Added staging site support for testing a connected Jetpack site + +Additional changes: + +* Enhancement: CLI: Added a possibility to change all options with confirmation for some of them +* Enhancement: Gallery: Added filters to allow new gallery types to be declared +* Enhancement: General: Added inline documentation for actions, filters, etc. +* Enhancement: General: Changed class variable declarations keyword from var to public +* Enhancement: General: Made the Settings page module toggle buttons more accessible +* Enhancement: General: The admin bar now loads new notifications popout +* Enhancement: General: Renamed some modules to avoid redundant prefixes +* Enhancement: General: Switched to the WordPress Core's spinner image +* Enhancement: General: Updated the bot list +* Enhancement: Manage: Added the ability to activate a network-wide plugin on a single site from WordPress.com +* Enhancement: Photon: Added a way to check image URLs against custom domains +* Enhancement: Photon: Added prompts on the media upload page telling the user about Photon +* Enhancement: Publicize: Added width and height values to OpenGraph tags for default images +* Enhancement: Related Posts: Added a filter to allow disabling nofollow +* Enhancement: REST API: Added new API endpoints to extend API functionality +* Enhancement: REST API: Added new fields to existing API endpoints +* Enhancement: Sharing: Added a possibility to opt-out of sharing for a single post +* Enhancement: Sharing: Added bbPress support +* Enhancement: Sharing: Added more configuration to the Likes modal +* Enhancement: Sharing: Made the reddit button open a new tab +* Enhancement: Sharing: Removed unused files +* Enhancement: Shortcodes: Added auto embed option inside comments +* Enhancement: Shortcodes: Added autohide parameter to the YouTube shortcode +* Enhancement: Subscriptions: added an action that triggers at the end of the subscription process +* Enhancement: VideoPress: Videos are now embedded using a new player +* Enhancement: Widget Visibility: Added parent page logic +* Enhancement: Widget Visibility: Added support for split terms +* Enhancement: Widgets: Added actions to the Social Media widget +* Enhancement: Widgets: Switched the Display Posts widget to the new API version +* Bug Fix: General: Fixed scrolling to top after modal window closing +* Bug Fix: Infinite Scroll: Added a check for cases when output buffering is disabled +* Bug Fix: Infinite Scroll: Added translation to the copyright message +* Bug Fix: Manage: Fixed automatic update synchronization on WordPress multisite network admin +* Bug Fix: Manage: Redirects back to WordPress.com are allowed from the customizer view +* Bug Fix: Media: Fixed duplicate images bug in the Media Extractor +* Bug Fix: Publicize: Made it possible to remove previously set message +* Bug Fix: Sharing: Added a thumbnail image to OpenGraph tags on pages with DailyMotion embeds +* Bug Fix: Sharing: Fixed Twitter Cards tags escaping +* Bug Fix: Sharing: Made OpenGraph tags for title and description use proper punctuation +* Bug Fix: Sharing: Made sure Likes can be disabled on the front page +* Bug Fix: Shortcodes: Fixed Facebook embeds by placing the scipt in the footer +* Bug Fix: Shortcodes: Fixed PollDaddy shortcode issues over SSL connections +* Bug Fix: Shortcodes: Made responsive video wrappers only wrap video embeds +* Bug Fix: Shortcodes: Made SoundCloud accept percents for dimensions +* Bug Fix: Social Links: Fixed a possible conflict with another class +* Bug Fix: Stats: Made sure the Stats URL is always escaped properly + += 3.6.1 = +Release Date: July 24, 2015 + +* Enhancement: Fully compatible with upcoming WordPress 4.3 +* Enhancement: Site Icon: Start to deprecate Site Icon in favor of Core's version (if available) +* Bug Fix: Subscriptions: You can now use more than one Subscription form on a single page +* Bug Fix: Quieted PHP notices and warnings with the JSON API, Display Posts Widget and Gallery Widget (slideshow mode) +* Bug Fix: Correct permissions check for connection panel +* Hardening: Increase permissions checks + += 3.6 = +Release Date: July 6th, 2015 +Release Post: http://wp.me/p1moTy-1ua + +Feature Enhancements: + +* CLI: Add a number of Jetpack CLI improvements: see http://jetpack.com/support/jetpack-cli +* New Jetpack admin page for connection management +* New Social Media Icons widget +* FB Like Box: A visual refresh of the Facebook likebox widget +* Protect: When your IP is blocked, use a math captcha as a fallback instead of a complete block + +Additional changes: + +* Enhancement: Custom CSS: Add more Flexbox support and other enhancements +* Enhancement: Extra Sidebar Widgets: Top Posts Widget: Choose what Post Types to display +* Enhancement: General: Save on some requests! print CSS inline when there isn't much of it +* Enhancement: Likes: Likes can now be shown on all post types +* Enhancement: Minileven: Add Featured Image to Gallery Post Format and Pages +* Enhancement: Mobile Theme: Add div wrapping View Mobile Site link to allow for easier CSS customizations +* Enhancement: Omnisearch: Link to edit post in titles +* Enhancement: Protect: Learn Trusted Headers locally and cache blocks properly +* Enhancement: REST API: Add locale support +* Enhancement: Sharing: Retire StumbleUpon +* Enhancement: Sharing: Upgrade to reCAPTCHA 2.0 for Email Sharing +* Enhancement: Shortcode Embeds: Add Mesh oembed support +* Enhancement: Shortcode Embeds: New Wufoo Shortcode from WordPress.com +* Enhancement: Shortcode Embeds: Mixcloud: handle accented characters in URLs +* Enhancement: Site Logo: Adding itemprops to support logo schema. +* Enhancement: Slideshow Gallery: New parameters *size* and *autostart* +* Enhancement: Slideshow Gallery: Use more reliable CSS for resizing instead of js +* Enhancement: Stats: No longer track stats for preview pages +* Enhancement: Tiled Gallery: Improve the shapes and distributions of shapes in the Tiled Gallery, based on observations for its usage. +* Enhancement: Protect: Whitelist for multisite globally and locally +* Enhancement: Sharing: LinkedIn always uses https for share counts. (saved extra http request) +* Bug Fix: Carousel: Jetpack Carousel now supports HTML5 gallery +* Bug Fix: Extra Sidebar Widgets: Choose Images button works in accessibility mode +* Bug Fix: General: Fix: Cannot remove hooks from filter 'jetpack_get_available_modules' +* Bug Fix: Infinite Scroll: Check that search terms exist before matching against post title. fixes #2075 +* Bug Fix: Likes: Never double show on search results +* Bug Fix: Notifications: Notifications didn't load on wp-admin/network pages +* Bug Fix: Sharing: Fix Facebook share button not showing for Australian & Canadian locale +* Bug Fix: Shortcode Embed: Slideshare Shortcode now fixed +* Bug Fix: SSO: Hide login no matter what when using the filter to do so +* Bug Fix: Subs Widget: Don't hide email input if submit failed +* Bug Fix: Tiled Gallery: Show columns setting for Thumbnail Grid when Tiled Mosaic galleries are the default +* Bug Fix: Twitter Cards: Remove deprecated card types + += 3.5.3 = +Release Date: May 6th, 2015 + +* Security Hardening: Remove Genericons example.html file. + += 3.5.2 = +Release Date: May 5th, 2015 + +* Bug Fix: Sharing: Changes Facebook share count endpoint + + += 3.5.1 = +Release Date: May 5th, 2015 + +* Enhancement: Sharing: Changes Facebook share count method per Facebook API change +* Enhancement: General: Remove .po files to reduce plugin size +* Bug Fix: General: Remove identity crisis notification +* Bug Fix: Subscriptions: Correct required input validation +* Security hardening + += 3.5 = +Release Date: April 23rd, 2015 +Release Post: http://wp.me/p1moTy-1jF + +Jetpack 3.5 introduces the ability to manage your site's menus directly from WordPress.com and several bug fixes and enhancements. This upgrade is recommended for all users. + +* Enhancement: General: Change security reporting to use a transient instead of option to reduce backup load +* Enhancement: General: Improve module search +* Enhancement: JSON API: Allow users to manage menus through WordPress.com +* Enhancement: Sharing: Reduce spam through email sharing +* Bug Fix: Custom CSS: Improve recall of CSS revisions +* Bug Fix: Extra Sidebar Widgets: Change class name for Contact Info widget +* Bug Fix: Extra Sidebar Widgets: Fix errors when adding widgets via the customizer +* Bug Fix: Extra Sidebar Widgets: Fix PHP notices in RSS widget +* Bug Fix: General: Fix redirect loop on activation +* Bug Fix: General: Styling fixes +* Bug Fix: Protect: Add IP translation fallback when inet_pton is not available +* Bug Fix: Protect: Always allow login from local IDs +* Bug Fix: Protect: Sanitize displayed IP after block +* Bug Fix: Publicize: Prevent generating Facebook profile links for app-scoped user IDs +* Bug Fix: Subscriptions: Improve error handling +* Bug Fix: Theme Tools: Include breadcrumb code +* Misc: Extra Sidebar Widgets: Remove Readmill Widget + += 3.4.3 = +Release Date: April 20th, 2015 +Release Post: http://wp.me/p1moTy-1jb + +* Security hardening. + += 3.4.2 = +Release Date: April 19th, 2015 +Release Post: http://wp.me/p1moTy-1j6 + +* Bug Fix: Contact info widget namespacing +* Bug Fix: Javascript errors on wp-admin due to stats display code +* Bug Fix: Potential fatal error from improperly called function +* Bug Fix: Potential fatal error when protect servers are unreachable for WordPress Multisite + += 3.4.1 = +Release Date: March 19th, 2015 + +* Bug Fix: General: Modules not displaying properly in non-English installs +* Bug Fix: Manage: Some installs showing a transient fatal error +* Bug Fix: Protect: Protect module not auto-activating for users who upgrade +* Bug Fix: Omnisearch: Some installs not properly reporting WP version number, causing Omnisearch error +* Bug Fix: Stats: Top posts/pages widget not loading +* Bug Fix: Contact Info Widget: Fix conflict with Avada theme + += 3.4 = +Release Date: March 18th, 2015 +Release Post: http://wp.me/p1moTy-1fU + +* Enhancement: Config Settings: provide a notification for users that update features settings +* Enhancement: Config Settings: provide a notification for users that update features settings +* Enhancement: Contact Form: Use the predefined $title variable in the anchor tag in grunion contact form button +* Enhancement: Contact Form: Use the predefined $title variable in the anchor tag in the button on admin +* Enhancement: Custom Content Type: Add all Custom Post Types to Omnisearch +* Enhancement: Custom Content Type: Add option to add Testimonial Custom Content Type in admin +* Enhancement: Custom Content Type: bring consistency between the portfolio and testimonial shared codebase +* Enhancement: Custom Content Type: code cleanup +* Enhancement: Custom Content Type: register namespaced 'jetpack_portfolio' shortcode/use a prefix for shortcode for Portfolio +* Enhancement: Custom Content Type: set shortcode image size to 'large' and add jetpack_portfolio_thumbnail_size filter to allow themes to set their own size for Portfolio +* Enhancement: Custom Content Type: testimonial shortcode enhancement +* Enhancement: Extra Sidebar Widgets: Add subscription widget wildcard +* Enhancement: Extra Sidebar Widgets: Likes and Sharing Shortcodes +* Enhancement: Extra Sidebar Widgets: Minor fixes to Facebook widget plugin for SSL +* Enhancement: Fix/update jetpack version +* Enhancement: General: Add DNS Prefetching +* Enhancement: General: Add Jetpack admin dashboard widget +* Enhancement: GlotPress: Update GP_Locales and GP_Locale classes +* Enhancement: Improved control over Nova Theme Menu output markup +* Enhancement: Infinite Scroll: Adds a `button` wrapper for the infinity handle. +* Enhancement: Infinite Scroll: Check for response.html before using indexOf +* Enhancement: Integrate BruteProtect for protection against Brute Force attacks +* Enhancement: JSON API Manage: Added Mock Jetpack Option to Sync options that don't have to live in the Database +* Enhancement: JSON API: Add/empty trash days option to sync +* Enhancement: Jump Start: Add "Jump Start" interface for new users +* Enhancement: Manage: Add "modified_before" and "modified_after" parameters to /sites/%s/posts/ via JSON API +* Enhancement: Mobile Theme: Add filter for choosing mobile theme menu +* Enhancement: Notifications: Changes to load the new notifications client. +* Enhancement: Protect: Add a filter so that user can add thier own bots +* Enhancement: Protect: Add security reporting +* Enhancement: Protect: Add/whitelist endpoints via JSON API for Jetpack Protect +* Enhancement: Publicize: update connection confirmation message +* Enhancement: Sharing: Add custom service name as a class +* Enhancement: Sharing: display name of custom service in link title +* Enhancement: Sharing: Remove default post types for showing share links +* Enhancement: Sharing: use Jetpack version number when enqueing sharing.js +* Enhancement: Shortcodes Team Partnerships: Backport fixes from SoundCloud 2.3.1 through 3.0.2 +* Enhancement: Shortlinks: use HTTPS when possible +* Enhancement: Stats: Make loading of stats async +* Enhancement: Subscriptions: Added settings field for comment sub text +* Enhancement: Subscriptions: Hide Form After Submit +* Enhancement: Subscriptions: remove label from widget title +* Enhancement: Subscriptions: Update subscriptions.php +* Bug Fix: Contact form: Increase CSS specificity for Contact Forms in widgets +* Bug Fix: Custom Content Type: Testimonial Custom Content Type: use core `WP_Customize_Image_Control` instead of custom... +* Bug Fix: Extra Sidebar Widgets: add missing & to if statement for widget visibility +* Bug Fix: Extra Sidebar Widgets: Don't require height/width values in the Twitter Timeline widget +* Bug Fix: Extra Sidebar Widgets: Upload images from the customizer/Extra Sidebar Widgets Tiled Galleries for Gallery Widget +* Bug Fix: General: Fix bug that was preventing modules from displaying properly +* Bug Fix: Manage: When calling /sites/%s/posts/ include all attachments not just the first five via JSON API +* Bug Fix: Mobile Theme: Minileven; Start after DOM ready +* Bug Fix: Sharing: Open sharing in same window +* Bug Fix: Stats language +* Bug Fix: Subscritpions: fix invalid field when no email address + + += 3.3.2 = +Release Date: February 19th, 2015 + +* Enhancement: Updated translation files. +* Enhancement: Heartbeat: Correctly stat new datasets. +* Bug Fix: Widget Visibility: Correct some caching of visibility results that may get evaluated too soon. +* Bug Fix: Contact Form: Hardening. +* Bug Fix: Photon: Make sure our gallery filter can parse array inputs as well as the default html. + += 3.3.1 = +Release Date: February 11th, 2015 + +* Bug Fix: JSON API: Minor versioning data. +* Bug Fix: Markdown: Re-run KSES after processing to account for syntax changes. +* Bug Fix: Media Extractor: Don't call a gallery a gallery if it hasn't got any pictures! +* Bug Fix: Module Management: Handle a core api change for folks running trunk. +* Bug Fix: Related Posts: CSS -- better clear rows. +* Bug Fix: Sharing: Including sharing account on Pinterest unofficial buttons as well. +* Bug Fix: Sharing: Properly version external assets by Jetpack release version. +* Bug Fix: Shortcodes: Soundcloud: Backport API compatibility fixes. +* Bug Fix: Shortcodes: Flickr: Tidy up our regex url pattern matching. +* Bug Fix: Subscriptions: Don't add 'Email Address' as the value -- we have placeholders! +* Bug Fix: Widgets: Gallery Widget: Allow folks to upload images from the widget area in the customizer. + += 3.3 = +Release Date: December 15th, 2014 +Release Post: http://wp.me/p1moTy-1aF + +* Enhancement: Adds responsive video support to BuddyPress. +* Enhancement: Custom Content Types: Added 'order' and 'orderby' options to portfolio shortcode. +* Enhancement: Display notice when Jetpack Development Mode is on. +* Enhancement: General: Update compatibility with Twenty Fifteen. +* Enhancement: Image URL can now be overwritten with the `jetpack_images_fit_image_url_override` filter after dimensions are set by Photon. +* Enhancement: JSON API: Add Endpoint for trigger Plugin Autoupdates. +* Enhancement: JSON API: General Improvements. Documentation on http://developer.wordpress.com/ +* Enhancement: Likes: Updated the code to accept arbitrary CPTs. +* Enhancement: Related Posts: Allow filter by `post_format`. +* Enhancement: Sharing: add new `jetpack_sharing_counts` filter for option to turn off sharing counts. +* Enhancement: Sharing: Use the Site Logo Theme Tool and the Site Icon as fallbacks for image tags. +* Enhancement: Shortcodes: Made the code more readable by using output buffers instead of string concatenation. +* Enhancement: Site Logo: Add alias functions to provide backward compatibility for themes expecting the old function calls. +* Enhancement: Slideshow: Add title and alt text to images. +* Enhancement: Subscription Form: Do not display the logged in user's email address by default. +* Enhancement: Top Posts Widget: Refactor to allow conditional loading of the css. +* Enhancement: Top Posts: Add `jetpack_top_posts_widget_count` filter to control number of displayed posts. +* Bug Fix: Change subscribe_text from `p` to `div` so that it can contain block-level elements. +* Bug Fix: Fonts: Change path to look for the svg in the right directory. +* Bug Fix: Increase CSS specificity for Contact Forms in widgets. +* Bug Fix: JSON API: Plugins Update: Make sure the plugin doesn't get deactivated. +* Bug Fix: Likes: Fixes issues where likes don't load, load master iframe after scripts are loaded. +* Bug Fix: Notes Module: Avoid a PHP Notice in cli scripts when the request doesn't contain a User-Agent header. +* Bug Fix: Nova Menu CPT: fix notice when we have no taxonomies. +* Bug Fix: Nova Menus: Use current instance to maintain object context. +* Bug Fix: Related Posts: Add filter for `_enabled_for_request()`. +* Bug Fix: Sharing: Prevent duplicate @ in shared Tweets. +* Bug Fix: Site Logo: `get_site_logo()` now properly returns the site logo ID when provided in the `$show` argument. +* Bug Fix: Site Logo: Correct evaluation of the Display Header Text in Customizer preview. + += 3.2.1 = +Release Date: November 14th, 2014 + +* Enhancement: Updated translation files. +* Enhancement: JSON API: More object vars passed back to some queries. Documentation on http://developer.wordpress.com/ +* Bug Fix: JSON API: Pass back correct author in `me/posts` data. +* Bug Fix: JSON API: Don't check if a post is freshly pressed on remote Jetpack sites where the function doesn't exist. +* Bug Fix: Site Logo: Add backward-compatible template tags to match the standalone release. +* Bug Fix: Don't use __DIR__ -- it's 5.3+ only, and WordPress supports back to 5.2. +* Bug Fix: Retool how we remove the source styles when using the concatenated version. +* Bug Fix: Shortcodes: TED: Correct default language code from `eng` to `en`. +* Bug Fix: Gallery Widget: Add a default background color. +* Bug Fix: Subscription Notifications: Remove the label. +* Bug Fix: Sharing: enqueue Genericons on static front page as well if selected. + += 3.2 = +Release Date: October 29, 2014 +Release Post: http://wp.me/p1moTy-181 + +* Enhancement: Speed Improvements (woohoo!). +* Enhancement: Add site icons: an avatar for your blog. +* Enhancement: Improvements to API endpoints. +* Enhancement: Add oEmbed sources (Twitter, SoundCloud, Instagram, DailyMotion, Vine). +* Enhancement: Add indicators to make it easier to see which modules are active. +* Enhancement: Improve debug tool. +* Enhancement: Add new 'Site Logos' code to theme tools, for themes that opt in to support it. +* Enhancement: Improved caching for related posts. +* Enhancement: Added "Remember Me" functionality to Single Sign On. +* Enhancement: Improved accessibility. +* Enhancement: Added additional filters to Widget Visibility. +* Bug Fix: Fixed PHP Notice errors for Likes, Widget Visibility. +* Bug Fix: Improvements to the testimonials CPT. +* Bug Fix: Improved RTL on VideoPress admin. +* Bug Fix: Removed Google+ Authorship module (discontinued by Google). +* Bug Fix: Fixed use of deprecated function in mobile theme. +* Bug Fix: Various fixes to Tiled Galleries. +* Bug Fix: Various fixes to Contact Form. +* Bug Fix: Various fixes to oEmbed. +* Bug Fix: Various fixes to Single Sign On. +* Bug Fix: Fixed styles in ShareDaddy. +* Bug Fix: Better match protocols (http/https) to the site. + + += 3.1.1 = +Release Date: August 7, 2014 + +* Enhancement: Update translation files for strings that had been submitted/approved since release. +* Bug Fix: Social Links: Add a function check to better degrade if Publicize isn't around. +* Bug Fix: Open Graph: Add WordPress SEO back to the blacklist, until they update how they opt us out. +* Bug Fix: Asset Minification: Add another caveat ( empty $plugin ) to short out on. +* Bug Fix: Deprecated Hooks: Fixing our expectations where something that should be an array occasionally wasn't. +* Bug Fix: Custom CSS: Add extra whitelist rule for -o-keyframe rules. + += 3.1 = +Release Date: July 31, 2014 +Release Post: http://wp.me/p1moTy-129 + +* Enhancement: New Custom Content Types module. +* Enhancement: New Jetpack Logo. +* Enhancement: New optional JSON API endpoints for viewing updates and managing plugins and themes. +* Enhancement: New Custom Post Type: Portfolio! +* Enhancement: Rearranged buttons on the modules modals for easier management. +* Enhancement: Jetpack Settings have improved keyboard accessibility. +* Enhancement: Improved RTL support for After the Deadline, Carousel, Contact Form, Comics CPT, Custom CSS, Omnisearch, Publicize, Related Posts, Slideshow short code, Tiled Gallery, Widget-Visibility and Widgets Gallery. +* Enhancement: Contact Form: Add an "Empty Spam" option. +* Enhancement: i18n: Change the priority of where plugin_textdomain is hooked so that the plugins can better translate Jetpack. +* Enhancement: Monitor: Displays how often the site is checked for downtime. +* Enhancement: Shortcode: Added Mixcloud shortcode and oEmbed support. +* Enhancement: Social Links: Improved handling of customizer hooks in non-admin context. +* Enhancement: Stats: The smiley image is gone by default. +* Enhancement: Stats: Added link to the configure page for stats so that the stats settings page is easier to find. +* Enhancement: Theme Tools: Added the responsive videos to theme tools so that themes can support responsive videos more easily. +* Update: Updated Genericons to version 3.1, new icons for website, ellipsis, foursquare, x-post, sitemap, hierarchy and paintbrush. +* Bug Fix: Contact Form: Prefix function to avoid conflicts with other plugins. +* Bug Fix: Custom CSS: Admin UI has a responsive layout. +* Bug Fix: Custom CSS: Custom $content_width value doesn't overwrite theme's $content_width. +* Bug Fix: Contact Form: Feedback link takes you to the form page. +* Bug Fix: Carousel: Confirms an avatar is returned by get_avatar before displaying. +* Bug Fix: Featured Content: Don't remove setting validation. +* Bug Fix: Infinite Scroll: Google Universal Analytics support added. +* Bug Fix: Multisite: Add message when updating multisite settings. +* Bug Fix: Photon: Photon will no longer upscale images larger than the original size. +* Bug Fix: Photon: Check that the image exists before rewriting the image URL to utilize Photon. +* Bug Fix: Sharing: Pinterest adds attribute to display share count. +* Bug Fix: Sharing: Respect an empty sharing title. +* Bug Fix: Sharing: Share buttons now appear in the bbPress forms. +* Bug Fix: Sharing: Support for multiple meta html tag og:image values. +* Bug Fix: Single Sign On: Logout allows override of forcing Single Sign On. +* Bug Fix: Single Sign On: Remove the lost password link on auto-forward logout. +* Bug Fix: Social Links: Do not use anonymous function for compatibility with PHP 5.2. +* Bug Fix: Tiled Galleries: Update jQuery mouseover caption effect to reduce flickering. +* Bug Fix: Widgets Visibility: Works better in the customizer admin view. + += 3.0.2 = +Release Date: June 17, 2014 + +* Enhancement: General: Make module categories filter more visible when active. +* Enhancement: General: Updated translation files with more strings added since the last release. +* Enhancement: General: Allow deep-linking to the Contact Support form. +* Bug Fix: General: RTL Jetpack Admin UI looks better. +* Bug Fix: General: Fixed PHP warning when bulk deactivating modules. +* Bug Fix: General: Removed an unnecessary description. +* Bug Fix: General: Resolved an SSL error on Jetpack Admin UI. +* Bug Fix: General: Fix error comparing signatures when the WordPress installation is using site_url filters (applied mostly to WPEngine sites). +* Bug Fix: General: Resolved PHP strict error on the mobile menu. +* Bug Fix: General: Fix timing of conditional checks, so that calling developer mode via a plugin works again. +* Bug Fix: General: Main page categories tab now properly translates module names. +* Bug Fix: Related Posts: Fix a typo, the "more info" link now works. +* Bug Fix: Likes: Improve button styling. +* Bug Fix: Likes: Remove unused UI for Reblog settings on social settings page. +* Bug Fix: Contact Form: Updated to no longer use a deprecated Akismet function. +* Bug Fix: Contact Form: Sends email to the administrator that is not marked as spam again. +* Bug Fix: Open Graph: Resolved PHP warning on open graph gallery pages when the gallery is empty. + += 3.0.1 = +Release Date: May 22, 2014 + +* Bug Fix: AtD: A wpcom-only function got synced by mistake and caused a few errors. Fixed. +* Bug Fix: Post By Email: Add static keyword to a function. +* Bug Fix: ShareDaddy: In the admin-side configuration of sharing links, we used a Path icon instead of Pinterest. Oops! +* Bug Fix: ShareDaddy: We inadvertently appended `via @jetpack` to some twitter shares. This is no longer the case. +* Bug Fix: Related Posts: Tidying up and relocation of the `resync` button formerly on the more info modal. +* Bug Fix: Infinite Scroll: Work better with core's MediaElement.js +* Bug Fix: Heartbeat: Undeclared variable fixed. + += 3.0 = +Release Date: May 20, 2014 +Release Post: http://wp.me/p1moTy-Wi + +* New User Interface for managing modules and settings +* New Module: Verfication Tools +* Enhancement: New look for the Sharing module +* Enhancement: Multiple improvements on which Twitter handle a Twitter card will display +* Enhancement: Add option to hide Google+ Authorship banner while still receiving the benefits +* Enhancement: Many Infinite Scroll enhancements to improve performance +* Enhancement: Infinite Scroll will use your CPT's display name instead of "Older Posts" +* Enhancement: JSON API added /media/new endpoint +* Enhancement: Added filter to assign new default image for Open Graph tags +* Enhancement: New [jetpack-related-posts] shortcode to add Related Posts to page instead of default placement +* Enhancement: Added SSO option to turn off login form completely, to use WordPress.com login exclusively +* Enhancement: The [googlemaps] shortcode allows for Google Maps Engine +* Enhancement: YouTube shortcode allows HD playback +* Enhancement: Smoother, Faster Tiled Galleries! +* Enhancement: New languages! Use Jetpack in Irish, Fulah, and Tigrinya +* Bug Fix: Use your browser's Back and Forward buttons when naviagating a Carousel +* Bug Fix: Various Related Posts fixes and improvements for added flexibility +* Bug Fix: WordPress 3.9: Restores ability to edit Contact Forms +* Bug Fix: WordPress 3.9: Restores Gallery Widget compatability +* Bug Fix: Ensure Markdown is kept when Bulk Editing posts +* Bug Fix: Improved Jetpack's Multisite Network Admin page for networks with a large number of sites +* Bug Fix: Ensure Sharing settings persist when Bulk Editing a post +* Bug Fix: Various other shortcode improvements + += 2.9.3 = +Release Date: April 10, 2014 +Release Post: http://wp.me/p1moTy-U2 + +* Important security update. CVE-2014-0173 + += 2.9.2 = +Release Date: March 17, 2014 + +* Bug Fix: Publicize: When publishing from a mobile app or third-party client, Publicize now works again. + += 2.9.1 = +Release Date: March 6, 2014 + +* Bug Fix: After the Deadline: Fix a Javascript glitch that could prevent publishing of posts. +* Bug Fix: SSO: Disable the implementation of an option that had been removed before release. This would have only been an issue if a site administrator had enabled the module during an early beta of 2.9. + += 2.9 = +Release Date: February 26, 2014 +Release Post: http://wp.me/p1moTy-RN + +* Added Multisite network functionality +* New Module: Related Posts +* Enhancement: Single Sign On +* Enhancement: Mixcloud shortcode and oEmbed +* Enhancement: Gist shortcode and oEmbed +* Enhancement: Modify Facebook Like Box widget to support new Facebook parameters +* Enhancement: Rolled the Push Notifications module into the Notes module +* Enhancement: Update kses with Markdown +* Enhancement: Adding keyboard accessibility to sharing buttons config page +* Enhancement: Pull WordPress testing bits from the new official git mirror at WordPress.org +* Bug Fix: Widget Visibility +* Bug Fix: Revisions box in Custom CSS +* Bug Fix: Fix several bugs in the WordPress Posts Widget so that it correctly updates +* Bug Fix: Limit Login Attempts no longer generates false positives from xmlrpc. +* Bug Fix: Clear max_posts transient on theme switch. +* Bug Fix: Lower priority of sync to allow all CPTs to be registered. +* Bug Fix: Contact form fields emailed in correct order. + +* Other bugfixes and enhancements at https://github.com/Automattic/jetpack/commits/2.9 + += 2.8 = +Release Date: January 31, 2014 +Release Post: http://wp.me/p1moTy-Pd + +* New Module: Markdown +* Module Update: Jetpack Monitor +* Enhancement: Infinite Scroll: Keep track of $current_day between requests so the_date() works well. +* Enhancement: Embeds: New filter to turn off embeds in comments. +* Enhancement: Contact Form: Add placeholder support. +* Enhancement: Widget: Gravatar Profile: Added filters to allow users to customize headings and fixed output of personal links. +* Enhancement: Facebook OG Tags: Add `published_time`, `modified_time`, and `author` if the post type supports it. +* Enhancement: Sharing: Display buttons on CPT archive pages. +* Enhancement: Sharing: Add `get_share_title` function and filter. +* Enhancement: Sharing: Add filter `sharing_display_link`. +* Enhancement: Twitter Timeline: Flesh out tweet limit option. +* Enhancement: Social Links: Add Google+ to the list of supported services. +* Enhancement: Stats: Improve dashboard styles in 3.8. +* Enhancement: Stats: No longer use Quantcast. +* Enhancement: Top Posts: Add `jetpack_top_posts_days` filter. +* Enhancement: AtD: Add TinyMCE 4 compatibility for its pending arrival in WordPress 3.9 +* Enhancement: Genericons: Update to v3.0.3 +* Enhancement: Tiled Galleries: Add alt attributes to images. +* Enhancement: Shortcode: YouTube: Accept protocol-relative URLs. +* Enhancement: Shortcode: Slideshow: Add white background option. +* Enhancement: Shortcode: YouTube: Add support for the two closed-caption arguments. +* Enhancement: Shortcode: Vimeo: Update the regex to support the new embed code. +* Enhancement: Shortcode: Google Maps: Update the regex to handle new format for embeds. +* Enhancement: Likes: Avoid a PHP Notice when $_POST['post_type'] is not set in meta_box_save. +* Enhancement: Smush images to save on file size. +* Enhancement: Publicize: Enable opt-in publicizing of custom post types. +* Bug Fix: Random Redirect: Further namespace to avoid conflicts. +* Bug Fix: Twitter Timeline: Resolve undefined index notice. +* Bug Fix: Featured Content: Add extra class_exists() check to be extra careful. +* Bug Fix: Facebook OG Tags: Change OG type of Home and Front Page to 'website' +* Bug Fix: Widget Visibility: Add support for old-style single use widgets. +* Bug Fix: Google Authorship: Support apostrophe in author names. +* Bug Fix: Media Extractor: Assorted graceful failure caveats. +* Bug Fix: Carousel: 'Link to None' bug fixed. +* Bug Fix: Embeds: Bandcamp: Switch escaping function for album and track IDs to handle (int)s greater than PHP_INT_MAX +* Bug Fix: Some plugins trying to catch brute-force attacks mistakenly flagged the Jetpack connection as one. + += 2.7 = +Release Date: December 11, 2013 +Release Post: http://wp.me/p1moTy-Mk + +* Enhancement: Google+ Publicize +* Enhancement: Add Cloudup as an oEmbed provider +* Enhancement: Subscriptions: Add subscribe_field_id filter to allow updated ids when using multiple widgets +* Enhancement: Infinite Scroll: TwentyFourteen Support +* Bug Fix: Contact Form: Fix warning when form is called outside the loop +* Bug Fix: Featured Content: Moving Settings to Customizer, provide option to set default tag as fallback, specify all supported post-types rather than just additional ones. Description Updates +* Bug Fix: Featured Content: Compat with 'additional_post_types' theme support argument. Comment updates +* Bug Fix: Featured Content: Make sure $term is an object before we treat it as one +* Bug Fix: GlotPress: Merge with latest GlotPress +* Bug Fix: Infinite Scroll: prevent Undefined index notice that can cause IS to fail when user has WP_DEBUG set to true +* Bug Fix: Infinite Scroll: Improved compatibility with Carousel, Tiled Galleries, VideoPress, and the `[audio]` and `[video]` shortcodes +* Bug Fix: Likes: Stop manually including version.php and trust the global. Some whitespace fixes, and if it's an attachment, follow the post_status of the parent post +* Bug Fix: Mobile Theme: Display password field for Gallery format protected posts +* Bug Fix: Sharing: Add new translation width for share button, and Google Plus icons +* Bug Fix: Shortcodes: Support Ineternational Google domains for maps +* Bug Fix: Shortcodes: Facebook Embeds: Register alternate permalink.php URL for posts +* Bug Fix: Subscriptions: Moved inline styles from widget email input to separate css file +* Bug Fix: Theme Tools: Fix glitch where random-redirect.php also showed as a plugin being deleted if you were deleting Jetpack +* Bug Fix: Misc: Internationalization & RTL updates +* Bug Fix: Misc: Prevent collisions with 'Facebook Featured Image & OG Meta Tags' plugin + += 2.6.1 = +Release Date: December 3, 2013 + +* Bug Fix: minor styling fix in pre- and post-MP6/3.8 UI changes. +* Bug Fix: Stats: spinner gif url fix when the user is viewing it over https. +* Bug Fix: Stats: Switch to esc_html from htmlspecialchars in error message -- better to be native +* Bug Fix: Media Extractor: some hosts don't compile unicode for preg_match_all, so we temporarily removed the block that depended on it. +* Bug Fix: Media Extractor: Add in some error handling for malformed URLs. +* Bug Fix: Twitter Cards: treat single-image galleries as a photo-type. +* Bug Fix: Update conflicting plugins for OG tags and Twitter Cards. +* Bug Fix: Correct max supported version number -- had been 3.6, update to 3.7.1 + += 2.6 = +Release Date: November 28, 2013 +Release Post: http://wp.me/p1moTy-KE + +* Enhancement: WPCC / now called [SSO](http://jetpack.com/support/sso/): refactored. +* Enhancement: Monitor: new module which will notify you if your site goes down(http://jetpack.com/support/monitor/). +* Enhancement: Custom CSS: replace Ace editor with Codemirror. +* Enhancement: Widgets: new “Display Posts” widget. +* Enhancement: WP-CLI: add commands to disconnect a site and manage modules. +* Enhancement: Contact Form: new filters, `grunion_contact_form_field_html` and `grunion_should_send_email`. +* Enhancement: Custom Post Types: new restaurant post type. +* Enhancement: Genericons: update to version 3.0.2. +* Enhancement: Infinite Scroll: many improvements and fixes. +* Enhancement: Likes: performance improvements. +* Enhancement: MP6: Jetpack icons are now compatible with WordPress 3.8. +* Enhancement: Open Graph: better descriptions, fallback images, and media extraction from video posts. +* Enhancement: Publicize: new background token tests for connected publicize services and display problems on settings sharing and add new post. +* Enhancement: Shortcodes: updated Bandcamp shortcode to support the `tracklist` and `minimal` attributes, as well as more `artwork` attribute values. +* Enhancement: Shortlinks: add Custom Post Type support. +* Enhancement: Subscriptions: add more ways to customize the subscriptions widget. +* Enhancement: Twitter Cards: better media management and card type detection, and better handling of conflicts with other Twitter Cards plugins. +* Enhancement: better handling of conflicts with other plugins. +* Bug Fix: After the Deadline: add a typeof check for `tinyMCEPreInit.mceInit` to prevent js errors. +* Bug Fix: Carousel: speed improvements and several bugfixes. +* Bug Fix: Contact Form: remove nonce creating issues with caching plugins. +* Bug Fix: Custom Post Types: Testimonials: return if featured image is empty so it can be removed after it’s been set. +* Bug Fix: Featured Content: add additional post type support through the `additional_post_types` argument. +* Bug Fix: Google Authorship: support apostrophes in Google+ profiles. +* Bug Fix: Google Authorship: use a regexp Instead of using `mb_convert_encoding`, which doesn’t enjoy universal support. +* Bug Fix: Heartbeat: ensure that it never triggers more than once per week. +* Bug Fix: JSON API: add new `?meta=` parameter that allows you to expand the data found in the `meta->links` responses. +* Bug Fix: JSON API: add new `is_private` response to the sites endpoint and `global_ID` response to the reader and post endpoints. +* Bug Fix: Mobile Theme: allow small images to display inline. +* Bug Fix: Mobile Theme: fix fatal errors for missing `minileven_header` function. +* Bug Fix: Photon: fix errors when an image is not uploaded properly. +* Bug Fix: Shortcodes: improvements to Archives, Google+, Presentations, Vine and Youtube. +* Bug Fix: Tiled Galleries: improve display of panoramic images and fix errors when an image is not uploaded properly. + += 2.5 = +Release Date: September 19, 2013 +Release Post: http://wp.me/p1moTy-xS + +* Enhancement: Connect your Google+ profile and WordPress site to prove authorship of posts. +* Enhancement: Improved sharing buttons display. +* Enhancement: Comment on your posts using Google+ to signin. +* Enhancement: Embed Google+ posts into your posts. +* Enhancement: Added event logging capabilities for debugging +* Enhancement: LaTeX is now available in dev mode +* Enhancement: Introduced gallery widget +* Enhancement: Added new module: VideoPress +* Enhancement: Updated identity crisis checker +* Enhancement: Tiled Gallery widget added +* Enhancement: Google +1 button changed to Google+ Share button, to avoid confusion +* Enhancement: Added check to ensure Google+ authorship accounts have disconnected properly +* Enhancement: Updated identity crisis checker +* Enhancement: Tiled Gallery widget added +* Enhancement: Google +1 button changed to Google+ Share button, to avoid confusion +* Enhancement: Added the ability to embed Facebook posts +* Bug Fix: Redirect issue with G+ authorship when WordPress is not in the root directory +* Enhancement: Better security if carousel to prevent self-XSS +* Enhancement: Better handling of cookies for subsites on multisite installs +* Bug Fix: Check for post in G+ authorship before accessing it + += 2.4.2 = +Release Date: September 5, 2013 + +* Enhancement: Converted to module headers to detect Auto-Activating modules. +* Enhancement: WPCC: Added 'Close' link to deactivate WPCC in the admin nag. +* Enhancement: JSON API: Add User Nicename to the user data. +* Bug Fix: Contact Form: Stopped using a short tag. +* Bug Fix: Changed CSS selector to catch MP6 stylings. +* Bug Fix: Dropped __FILE__ references in class.jetpack.php in favor of JETPACK__PLUGIN_DIR constant, now code that deactivates the plugin from the connect nag works again. +* Bug Fix: Random Redirect: Add random-redirect to the plugins overriden list, in case someone is using Matt's Random Redirect plugin. +* Bug Fix: Tiled Gallery: Revert r757178 relating to tiled gallery defaults. +* Bug Fix: Return false, not zero, if $GLOBALS['content_width'] isn't defined. +* Bug Fix: WPCC: Don't call wp_login_url() in the constructor -- if someone is running a custom login page, that can break things if their plugin runs get_permalink as a filter before init. +* Bug Fix: Tiled Gallery: Add fallback if post_parent == 0 due to infinite_scroll_load_other_plugins_scripts. +* Bug Fix: Custom CSS: Set the ACE gutter z-index to 1. +* Bug Fix: Custom Post Types: Switch from wp_redirect() to wp_safe_redirect(). +* Bug Fix: Likes: Set overflow:hidden; on the likes adminbar item. +* Bug Fix: Mobile Theme: Migrate where/when the custom header stuff is included. +* Bug Fix: Slideshow Shortcode: Add a height of 410px. + += 2.4.1 = +Release Date: September 4, 2013 + +* Enhancement: Don't auto-activate WPCC. + += 2.4 = +Release Date: August 30, 2013 +Release Post: http://wp.me/p1moTy-wv + +* Enhancement: WordPress.com Connect (WPCC): New Module. +* Enhancement: Widget Visibility: New Module. +* Enhancement: Shortcode: Addition of new Twitter Timeline shortcode. +* Enhancement: Shortcode: Addition of new Presentation shortcode. +* Enhancement: Shortcode: Addition of new Vine shortcode. +* Enhancement: Custom Post Types: CPTs are available. +* Enhancement: Subscriptions: Add 'jetpack_is_post_mailable' filter. +* Enhancement: OpenGraph: Add Twitter Cards meta tags as well. +* Enhancement: Custom CSS: Update lessc and scssc preprocessors to 0.4.0 and 0.0.7 respectively. +* Enhancement: Omnisearch: Add Media results. +* Enhancement: Likes: Use a protocol-agnostic iframe, instead of forced HTTPS. +* Enhancement: Top Posts: Increase post limit. +* Enhancement: Publicize: Updated JS and UI. +* Enhancement: Photon: New filter to let site admins/owners enable photon for HTTPS urls. +* Enhancement: New jetpack_get_available_modules filter. +* Enhancement: Subscriptions: Antispam measures. +* Bug Fix: Add inline style to keep plugins/themes from inadvertently hiding the Connect box. +* Bug Fix: Custom CSS: Respect the new wp_revisions_to_keep filter. +* Bug Fix: Photon: Only hook jetpack_photon_url into the filter if the user has Photon active. +* Bug Fix: Heartbeat: Used wrong object, occasinally fatal-erroring out for the cron. +* Bug Fix: Add an empty debug.php file to the /modules/ folder, to solve some update issues where it never got deleted. + += 2.3.5 = +Release Date: August 12, 2013 +Release Post: http://wp.me/p1moTy-vf + +* Enhancement: Added Path support to Publicize. + += 2.3.4 = +Release Date: August 6, 2013 +Release Post: http://wp.me/p1moTy-uL + +* Bug Fix: Correct when output occurs with CSV export for feedback. +* Bug Fix: Tidy up the Heartbeat API. +* Enhancement: User Agent: Improve detecting of bots. +* Enhancement: Genericons: Make sure we're pulling the freshest version from genericons.com on each release. +* Enhancement: JSON API: Open up replies/new endpoints so that users can comment on blogs that are not in their access token. +* Enhancement: Photon: Apply to `get_post_gallery()` function as well. +* Enhancement: Tiled Galleries: Add a default bottom margin to be more robust out of the box. +* Translations: Adding in fresher translation files. +* Deprecation: Removing the retinization code for 3.4, as it was included in WordPress trunk from 3.5 onwards. + += 2.3.3 = +Release Date: July 26, 2013 +Release Post: http://wp.me/p1moTy-uv + +* Bug Fix: We were inadvertently overwriting cron schedules with our Jetpack heartbeat. This should now be fixed. +* Enhancement: New Facebook Sharing icons. +* Enhancement: Minor update to the Minileven stylesheet. + += 2.3.2 = +Release Date: July 25, 2013 +Release Post: http://wp.me/p1moTy-uv + +* Bug Fix: Fixed an issue where Facebook Pages were not available when connecting a Publicize account. +* Bug Fix: For some web hosts, fixed an issue where 'Jetpack ID' error would occur consistently on connecting to WordPress.com. +* Enhancement: Adding some new stats and heartbeat checking to Jetpack. + += 2.3.1 = +Release Date: July 2, 2013 +Release Post: http://wp.me/p1moTy-t9 + +* Enhancement: Social Links: Retooling the class for better consistency and performance behind the scenes. +* Enhancement: Omnisearch: Make it easier to search Custom Post Types. No longer need to extend the class, if all you want is a basic display. Just call `new Jetpack_Omnisearch_Posts( 'cpt' );` +* Enhancement: Sharing Buttons: LinkedIn: Use the official button's sharing link on the Jetpack implementation for a more consistent sharing experience and produce better results on LinkedIn's end. +* Enhancement: Debug / Connection: Better logic in determining whether the server can use SSL to connect to WPCOM servers. +* Enhancement: Sharing: Twitter: Calculate the size of the Tweet based on the short URL rather than the full URL size. +* Enhancement: Debug: More readable and understandable messages. +* Enhancement: Likes: Including some MP6 styles. +* Enhancement: Comments: Add new core classes to comment form. See http://core.trac.wordpress.org/changeset/24525 +* Bug Fix: Omnisearch: Don't load everything initially, run the providers off admin_init, and then issue an action for folks to hook into. +* Bug Fix: Omnisearch: Modify some child class functions to match the parent's parameters and avoid strict notices in newer versions of PHP. +* Bug Fix: Omnisearch: Hide the search form in the module description if the current user can't use it. +* Bug Fix: Comment Form: Use edit_pages, not edit_page (fixes glitch in previous beta, never publicly released). +* Bug Fix: Twitter Timeline Widget: Additional testing of values and casting to default if they are nonconforming. +* Bug Fix: Sharing: Pinterest: Make the button wider if there's a count to avoid overlapping with others. +* Bug Fix: Post By Email: Change configuration_redirect to static. +* Bug Fix: Likes: Don't call configuration_redirect as a static, do it as a method. +* Bug Fix: Add some further security measures to module activation. + += 2.3 = +Release Date: June 19, 2013 +Release Post: http://wp.me/p1moTy-rX + +* Enhancement: Omnisearch: Search once, get results from everything! Omnisearch is a single search box that lets you search many different things +* Enhancement: Debugger: this module helps you debug connection issues right from your dashboard, and contact the Jetpack support team if needed +* Enhancement: Social Links: this module is a canonical source, based on Publicize, that themes can use to let users specify where social icons should link to +* Enhancement: It’s now easier to find out if a module is active or note, thanks to the new Jetpack::is_module_active() +* Enhancement: Contact Form: You are now able to customize the submit button text thanks to the submit_button_text parameter +* Enhancement: Comments: We've added a filter to let users customize the Comment Reply label, and users can now also customize the prompt on the comment form again. +* Enhancement: Mobile Theme: Add genericons.css and registering it so it’s easily accessible to other modules that may want it +* Enhancement: Tiled Galleries: You can now customize the captions, thanks to the jetpack_slideshow_slide_caption filter +* Enhancement: Widgets: Twitter Timeline: Add the noscrollbar option +* Enhancement: Widgets: Facebook Like Box Widget: add a show_border attribute +* Enhancement: Widgets: FB Like Box: let Jetpack users override the iframe background color set in an inline style attribute by using the jetpack_fb_likebox_bg filter +* Bug Fix: Carousel: Fix a bug where double-clicking a gallery thumbnail broke the carousel functionality +* Bug Fix: Comments: Change “must-log-in” to class from ID +* Bug Fix: Contact Form: Make the Add Contact Form link a button, ala Add Media in core +* Bug Fix: Contact Form: Fix encoding of field labels +* Bug Fix: Contact Form: Remove references to missing images +* Bug Fix: Fix 2 XSS vulnerabilities +* Bug Fix: JSON API: Minor fixes for bbPress compatibility +* Bug Fix: JSON API: Fix metadata bugs +* Bug Fix: JSON API: Add a new hook that is fired when a post is posted using the API +* Bug Fix: JSON API: Prefork/REST: update path normalizer to accept versions other than 1 +* Bug Fix: JSON API: Remove extra parenthesis in CSS +* Bug Fix: Custom CSS: Move content width filters higher up so that they’re active for all users, not just logged-in admins. +* Bug Fix: Custom CSS: All CSS properties that accept images as values need to be allowed to be declared multiple times so that cross-browser gradients work +* Bug Fix: Infinite Scroll: Allow themes to define a custom function to render the IS footer +* Bug Fix: Infinite Scroll: Fix up Twenty Thirteen styles for RTL and small viewports. +* Bug Fix: Likes: Fix ‘Call to undefined function’ +* Bug Fix: Likes: Add scrolling no to iframe to make sure that like button in admin bar does not show scrollbars +* Bug Fix: Likes: Remove setInterval( JetpackLikesWidgetQueueHandler, 250 ) call that was causing heavy CPU load +* Bug Fix: Mobile Theme: Remove unused variable & function call +* Bug Fix: Publicize: Fix LinkedIn profile URL generation +* Bug Fix: Publicize: Better refresh handling for services such as LinkedIn and Facebook +* Bug Fix: Shortcodes: Audio shortcode: Treat src as element 0. Fixes audio shortcodes created by wp_embed_register_handler when an audio url is on a line by itself +* Bug Fix: Bandcamp: Updates to the Bandcamp shortcode +* Bug Fix: Stats: Fix missing function get_editable_roles on non-admin page loads +* Bug Fix: Widgets: Twitter Timeline: Fix HTML links in admin; set default values for width/height; change some of the sanitization functions +* Bug Fix: Widgets: Top Posts Widget: Exclude attachments +* Bug Fix: Widgets: Top Posts Widget: fix data validation for number of posts +* Bug Fix: Fix PHP warnings non-static method called dynamically +* Bug Fix: Fixed an issue in image extraction from HTML content +* Bug Fix: Open Graph: Change default minimum size for og:image too 200×200 +* Note: The old Twitter widget was removed in favour of Twitter Timeline widget +* Note: Add is_module_active() to make it easier to detect what is and what isn’t +* Note: Compressing images via lossless methods +* Note: Tidying up jetpack’s CSS +* Note: Set the max DB version for our retina overrides that were meant to stop for WordPress 3.5 +* Note: Updating spin.js to the current version, and shifting to the canonical jquery.spin.js library +* Note: Adding Jetpack_Options class, and abstracting out options functions to it + += 2.2.5 = +Release Date: May 1, 2013 +Release Post: http://wp.me/p1moTy-p8 + +* Enhancement: Stats: Counting of registered users' views can now be enabled for specific roles +* Bug Fix: Security tightening for metadata support in the REST API +* Bug Fix: Update the method for checking Twitter Timeline widget_id and update coding standards +* Bug Fix: Custom CSS: Allow the content width setting to be larger than the theme's content width +* Bug Fix: Custom CSS: Fix possible missing argument warning. + += 2.2.4 = +Release Date: April 26, 2013 +Release Post: http://wp.me/p1moTy-oU + +* Bug Fix: JSON API compat file include was not assigning a variable correctly, thus throwing errors. This has been resolved. + += 2.2.3 = +Release Date: April 26, 2013 +Release Post: http://wp.me/p1moTy-oR + +* Enhancement: Comments - Add the reply-title H3 to the comment form so that themes or user CSS can style it +* Enhancement: Custom CSS - Support for the CSS @viewport +* Enhancement: JSON API - Support for i_like, is_following, and is_reblogged +* Enhancement: JSON API: Custom Post Type Support +* Enhancement: JSON API: Meta Data Support +* Enhancement: JSON API: Bundled Support for bbPress +* Enhancement: JSON API: Additions of following, reblog, and like status for post endpoints. +* Enhancement: Shortcodes - Add Bandcamp shortcode +* Enhancement: Tiled Galleries - Add code to get blog_id +* Bug Fix: Carousel - Support relative image paths incase a plugin is filtering attachment URLs to be relative instead of absolute +* Bug Fix: Carousel - Add likes widget to images / Respect comment settings for name/email +* Bug Fix: Carousel - Make name and email optional if the setting in the admin area says they are +* Bug Fix: Contact Form - Bug fixes, including a fix for WP-CLI +* Bug Fix: Contact Form - Remove deprecated .live calls, delegate lazily to jQuery(document) since it's all in an iframe modal +* Bug Fix: Contact Form - RTL styles +* Bug Fix: Contact Form - Better handle MP6 icons +* Bug Fix: Custom CSS - array_shift() took a variable by reference, so avoid passing it the result of a function +* Bug Fix: Custom CSS - Allow case-insensitive CSS properties (ref) +* Bug Fix: Infinite Scroll - Maintain main query's `post__not_in` values when querying posts for IS +* Bug Fix: Infinite Scroll - Ensure that IS's `pre_get_posts` method isn't applied in the admin. Also fixes an incorrect use of `add_filter()` where `add_action()` was meant. Fixes #1696-plugins +* Bug Fix: Infinite Scroll - CSS update - IS footer was too large in Firefox +* Bug Fix: Infinite Scroll - Add bundled support for Twenty Thirteen default theme +* Bug Fix: Infinite Scroll - Include posts table's prefix when modifying the SQL WordPress generates to retrieve posts for Infinite Scroll +* Bug Fix: JSON API - Use wp_set_comment_status to change the comment status, to make sure actions are run where needed +* Bug Fix: Likes - Update style and logic for matching id's +* Bug Fix: Mobile Theme - Ensure that minileven_actual_current_theme() is child-theme compatible + other updates +* Bug Fix: Mobile Theme - Update method for finding currently active theme. +* Bug Fix: Notifications - Remove the postmessage.js enqueue since this feature solely supports native postMessage +* Bug Fix: Notifications - Clean up script enqueues and use core versions of underscore and backbone on wpcom as fallbacks +* Bug Fix: Notifications - Enqueue v2 scripts and style +* Bug Fix: Notifications - Prefix module-specific scripts and style to prevent collision +* Bug Fix: Notifications - Include lang and dir attributes on #wpnt-notes-panel so the notifications iframe can use these to display correctly +* Bug Fix: Open Graph: Use the profile OG type instead of author. Add tags for first/last names +* Bug Fix: Publicize - Remove the Yahoo! service because they stopped supporting that API entirely +* Bug Fix: Publicize - fix fatal errors caused by using a method on a non-object. Props @ipstenu +* Bug Fix: Sharing - Adding 2x graphics for Pocket sharing service +* Bug Fix: Sharing - Bug fixes, and a new filter +* Bug Fix: Shortcodes - Audio: make sure that the Jetpack audion shortcode does not override the 3.6 core audio shortcode. Also, we need to filter the old Jetpack-style shortcode to properly set the params for the Core audio shortcode. +* Bug Fix: Shortcodes - Audio: Re-enable the flash player +* Bug Fix: Shortcodes - Slideshow: RTL styling update +* Bug Fix: Tiled Galleries - Fix IE8 display bug where it doesn't honor inline CSS for width on images +* Bug Fix: Tiled Galleries - Remove depreacted hover call, use mouseenter mouseleave instead +* Enhancement: Twitter Timeline Widget: New JavaScript based widget. Old one will discontinue May 7th. + += 2.2.2 = +Release Date: April 5, 2013 + +* Enhancement: Mobile Theme: Add controls for custom CSS. +* Enhancement: Sharing: Add Pocket to the available services. +* Bug Fix: Custom CSS: Update the method for generating content width setting. +* Bug Fix: JSON API: Security updates. +* Bug Fix: Likes: Add settings for email notifications and misc style updates. +* Bug Fix: Notifications: Add the post types to sync after init. +* Bug Fix: Publicize: RTL styling. +* Bug Fix: Shortcodes: security fixes and function prefixing. +* Bug Fix: Widgets: Update wording on the Top Posts widget for clarity. +* Bug Fix: Jetpack Post Images security fixes. + += 2.2.1 = +Release Date: March 28, 2013 +Release Post: http://wp.me/p1moTy-ob + +* Enhancement: Development Mode: Define the `JETPACK_DEV_DEBUG` constant to `true` to enable an offline mode for localhost development. Only modules that don't require a WordPress.com connection can be enabled in this mode. +* Enhancement: Likes: Added the number of likes to the wp-admin/edit.php screens. +* Enhancement: Mobile Theme - design refresh +* Enhancement: Shortcodes - Add a filter to the shortcode loading section so that a plugin can override what Jetpack loads for shortcodes +* Enhancement: Widgets - Filter Jetpack's widgets so that a plugin can control which widgets get loaded +* Bug Fix: Comments - Add in a wrapper div with id='commentform' +* Bug Fix: Contact Form - Added date field with datepicker +* Bug Fix: Contact Form - Allowed non-text widgets to use contact forms by running their output through the widget_text filter +* Bug Fix: Custom CSS - Allowing color values to be defined multiple times +* Bug Fix: Custom CSS - Dynamically loading the correct CSS/LESS/SCSS mode for the CSS editor if the user changes the preprocessor +* Bug Fix: Custom CSS - Using the unminified worker CSS +* Bug Fix: Custom CSS - Added rule: reminder about using .custom-background on body selector +* Bug Fix: Custom CSS - Modified rule: Removed portion of overqualification rule that deems 'a.foo' overqualified if there are no other 'a' rules +* Bug Fix: Custom CSS - Ensuring that the editor and the textarea behind it are using the same font so that the cursor appears in the correct location +* Bug Fix: Custom CSS - Fix a bug that caused some sites to always ignore the base theme's CSS when in preview mode +* Bug Fix: Custom CSS - Run stripslashes() before passing CSS to save() +* Bug Fix: Custom CSS - Moving inline CSS and JavaScript into external files +* Bug Fix: Infinite Scroll - Use the `is_main_query()` function and query method +* Bug Fix: Infinite Scroll - Remove unused styles and an unnecessary margin setting +* Bug Fix: Infinite Scroll - Allow the query used with IS to be filtered, so IS can be applied to a new query within a page template +* Bug Fix: JSON API - Catch the 'User cannot view password protected post' error from can_view_post and bypass it for likes actions if the user has the password entered +* Bug Fix: Likes - Bump cache buster, Don't show likes for password protected posts +* Bug Fix: Notifications - Remove a redundant span closing tag +* Bug Fix: Photon - If an image is already served from Photon but the anchor tag that surrounds it hasn't had its `href` value rewritten to use Photon, do so. Accounts for WP galleries whose individual items are linked to the original image files +* Bug Fix: Publicize - Allows GLOBAL_CAP to be filtered, Adds an AYS to connection deletion, UI improvement for MP6 (and in general) +* Bug Fix: Sharedaddy - Fire the sharing redirect earlier for increased plugin compatibility +* Bug Fix: Stats - Move the display:none CSS output to wp_head so it gets written inside the HEAD tag if the option to hide the stats smilie is active +* Bug Fix: Tiled Galleries - A more descriptive name for the default gallery type +* Bug Fix: Tiled Galleries - Hide the Columns setting for gallery types that don't support it +* Bug Fix: Run the admin_menu action late so that plugins hooking into it get a chance to run +* Bug Fix: Prophylactic strict equality check + += 2.2 = +Release Date: February 26, 2013 +Release Post: http://wp.me/p1moTy-ns + +* Enhancement: Likes: Allow your readers to show their appreciation of your posts. +* Enhancement: Shortcodes: SoundCloud: Update to version 2.3 of the SoundCloud plugin (HTML5 default player, various fixes). +* Enhancement: Shortcodes: Subscriptions: Add a shortcode to enable placement of a subscription signup form in a post or page. +* Enhancement: Sharedaddy: Allow selecting multiple images from a post using the Pinterest share button. +* Enhancement: Contact Form: Allow feedbacks to be marked spam in bulk. +* Enhancement: Widgets: Readmill Widget: Give your visitors a link to send your book to their Readmill library. +* Note: Notifications: Discontinue support for Internet Explorer 7 and below. +* Bug Fix: JSON API: Fix authorization problems that some users were experiencing. +* Bug Fix: JSON API: Sticky posts were not being sorted correctly in /posts requests. +* Bug Fix: Stats: sync stats_options so server has roles array needed for view_stats cap check. +* Bug Fix: Infinite Scroll: Display improvements. +* Bug Fix: Infinite Scroll: WordPress compatibility fixes. +* Bug Fix: Photon: Only rewrite iamge urls if the URL is compatible with Photon. +* Bug Fix: Photon: Account for registered image sizes with one or more dimesions set to zero. +* Bug Fix: Subscriptions: Make HTML markup more valid. +* Bug Fix: Subscriptions: Fixed notices displayed in debug mode. +* Bug Fix: Custom CSS: CSS warnings and errors should now work in environments where JavaScript is concatenated or otherwise modified before being served. +* Bug Fix: Hovercards: WordPress compatibility fixes. +* Bug Fix: Improved image handling for the Sharing and Publicize modules. +* Bug Fix: Carousel: Display and Scrollbar fixes. +* Bug Fix: Tiled Galleries: Restrict images in tiled galleries from being set larger than their containers. +* Bug Fix: Widgets: Gravatar Profile: CSS fixes. +* Bug Fix: Publicize: Strip HTML comments from the data we send to the third party services. +* Bug Fix: Notifications: Dropped support for IE7 and below in the notifications menu. +* Bug Fix: Custom CSS Editor: Allow custom themes to save CSS more easily. +* Bug Fix: Infinite Scroll: Waits until the DOM is ready before loading the scrolling code. +* Bug Fix: Mobile Theme: If the user has disabled the custom header text color, show the default black header text color. +* Bug Fix: Mobile Theme: Fix for the "View Full Site" link. +* Bug Fix: Mobile Theme: Use a filter to modify the output of wp_title(). +* Bug Fix: Publicize: Twitter: Re-enable character count turning red when more than 140 characters are typed. + += 2.1.2 = +Release Date: February 5, 2013 + +* Enhancement: Infinite Scroll: Introduce filters for Infinite Scroll. +* Enhancement: Shortcodes: TED shortcode. +* Bug Fix: Carousel: Make sure to use large image sizes. +* Bug Fix: Carousel: Clicking the back button in your browser after exiting a carousel gallery brings you back to the gallery. +* Bug Fix: Carousel: Fix a scrollbar issue. +* Bug Fix: Comments: Move the get_avatar() function out of the base class. +* Bug Fix: Contact Form: Prevent the form from displaying i18n characters. +* Bug Fix: Contact Form: Remove the !important CSS rule. +* Bug Fix: Infinite Scroll: Main query arguments are not respected when using default permalink. +* Bug Fix: JSON API: Trap 'wp_die' for new comments and image uploads. +* Bug Fix: JSON API: Use a better array key for the user_ID. +* Bug Fix: JSON API: Make the class instantiable only once, but multi-use. +* Bug Fix: JSON API: Fix lookup of pages by page slug. +* Bug Fix: JSON API: Updates for post likes. +* Bug Fix: Mobile Theme: Remove Android download link for BB10 and Playbook. +* Bug Fix: Open Graph: Stop using Loop functions to get post data for meta tags. +* Bug Fix: Photon: Suppress and check for warnings when pasing_url and using it. +* Bug Fix: Photon: Ensure full image size can be used. +* Bug Fix: Photon: Resolve Photon / YouTube embed conflict. +* Bug Fix: Photon: Fix dimension parsing from URLs. +* Bug Fix: Photon: Make sure that width/height atts are greater than zero. +* Bug Fix: Sharedaddy: Layout fixes for share buttons. +* Bug Fix: Sharedaddy: Always send Facebook a language locale. +* Bug Fix: Sharedaddy: Don't look up share counts for empty URLs. +* Bug Fix: Shortcodes: Ensure that images don't overflow their containers in the slideshow shortcode. +* Bug Fix: Shortcodes: only enqueue jquery if archive supports Infinite Scroll in the Audio Shortcode. +* Bug Fix: Tiled Galleries: Use a more specific class for gallery item size to avoid conflicts. +* Bug Fix: Tiled Galleries: Fixing scrolling issue when tapping on a Tiled Gallery on Android. +* Bug Fix: Widgets: Gravatar profile widget typo. +* Bug Fix: Widgets: Add (Jetpack) to widget titles. +* Bug Fix: Widgets: Twitter wasn't wrapping links in the t.co shortener. +* Bug Fix: Widgets: Facebook Likebox updates to handling the language locale. +* Bug Fix: Widgets: Top Posts: Fixed a WP_DEBUG notice. +* Bug Fix: Widgets: Gravatar Profile Widget: transient names must be less than 45 characters long. +* Bug Fix: typo in delete_post_action function. +* Bug Fix: Load rendered LaTeX image on same protocol as its page. + + += 2.1.1 = +Release Date: January 5, 2013 +Release Post: http://wp.me/p1moTy-ng + +* Bug Fix: Fix for an error appearing for blogs updating from Jetpack 1.9.2 or earlier to 2.1. + += 2.1 = +Release Date: January 4, 2013 +Release Post: http://wp.me/p1moTy-m3 + +* Enhancement: Tiled Galleries: Show off your photos with cool mosaic galleries. +* Enhancement: Slideshow gallery type: Display any gallery as a slideshow. +* Enhancement: Custom CSS: Allow zoom property. +* Enhancement: Stats: Show WordPress.com subscribers in stats. +* Bug Fix: Fix errors shown after connecting Jetpack to WordPress.com. +* Bug Fix: Photon: Fix bug causing errors to be shown in some posts. +* Bug Fix: Photon: Convert all images in posts when Photon is active. +* Bug Fix: Infinite Scroll: Improved compatibility with the other modules. +* Bug Fix: Custom CSS: Updated editor to fix missing file errors. +* Bug Fix: Publicize: Don't show the Facebook profile option if this is a Page-only account. +* Bug Fix: Photon: A fix for photos appearing shrunken if they didn't load quickly enough. +* Bug Fix: Sharing: A compatibility fix for posts that only have partial featured image data. +* Bug Fix: Publicize/Sharing: For sites without a static homepage, don't set the OpenGraph url value to the first post permalink. +* Bug Fix: Mobile Theme: Better compatibility with the customizer on mobile devices. +* Bug Fix: Sharing: Don't show sharing options on front page if that option is turned off. +* Bug Fix: Contact Form: Fix PHP warning shown when adding a Contact Form in WordPress 3.5. +* Bug Fix: Photon: Handle images with relative paths. +* Bug Fix: Contact Form: Fix compatibility with the Shortcode Embeds module. + + += 2.0.4 = +Release Date: December 14, 2012 +Release Post: http://wp.me/p1moTy-lT + +* Bug Fix: Open Graph: Correct a bug that prevents Jetpack from being activated if the SharePress plugin isn't installed. + += 2.0.3 = +Release Date: December 14, 2012 +Release Post: http://wp.me/p1moTy-lJ + +* Enhancement: Infinite Scroll: support [VideoPress](http://wordpress.org/extend/plugins/video/) plugin. +* Enhancement: Photon: Apply to all images retrieved from the Media Library. +* Enhancement: Photon: Retina image support. +* Enhancement: Custom CSS: Refined editor interface. +* Enhancement: Custom CSS: Support [Sass](http://sass-lang.com/) and [LESS](http://lesscss.org/) with built-in preprocessors. +* Enhancement: Open Graph: Better checks for other plugins that may be loading Open Graph tags to prevent Jetpack from doubling meta tag output. +* Bug Fix: Infinite Scroll: Respect relative image dimensions. +* Bug Fix: Photon: Detect custom-cropped images and use those with Photon, rather than trying to use the original. +* Bug Fix: Custom CSS: Fix for bug preventing @import from working with url()-style URLs. + += 2.0.2 = +Release Date: November 21, 2012 +Release Post: http://wp.me/p1moTy-lu + +* Bug Fix: Remove an erroneous PHP short open tag with the full tag to correct fatal errors under certain PHP configurations. + += 2.0.1 = +Release Date: November 21, 2012 +Release Post: http://wp.me/p1moTy-lc + +* Enhancement: Photon: Support for the [Lazy Load](http://wordpress.org/extend/plugins/lazy-load/) plugin. +* Bug Fix: Photon: Fix warped images with un- or under-specified dimensions. +* Bug Fix: Photon: Fix warped images with pre-photonized URLs; don't try to photonize them twice. +* Bug Fix: Infinite Scroll: Check a child theme's parent theme for infinite scroll support. +* Bug Fix: Infinite Scroll: Correct a bug with archives that resulted in posts appearing on archives that they didn't belong on. +* Bug Fix: Publicize: Send the correct shortlink to Twitter (et al.) if your site uses a shortener other than wp.me. +* Bug Fix: Sharing: Improved theme compatibility for the Google+ button. +* Bug Fix: Notifications: Use locally-installed Javascript libraries if available. + += 2.0 = +Release Date: November 8, 2012 +Release Post: http://wp.me/p1moTy-jg + +* Enhancement: Publicize: Connect your site to popular social networks and automatically share new posts with your friends. +* Enhancement: Post By Email: Publish posts to your blog directly from your personal email account. +* Enhancement: Photon: Images served through the global WordPress.com cloud. +* Enhancement: Infinite Scroll: Better/faster browsing by pulling the next set of posts into view automatically when the reader approaches the bottom of the page. +* Enhancement: Open Graph: Provides more detailed information about your posts to social networks. +* Enhancement: JSON API: New parameters for creating and viewing posts. +* Enhancement: Improved compatibility for the upcoming WordPress 3.5. +* Bug Fix: Sharing: When you set your sharing buttons to use icon, text, or icon + text mode, the Google+ button will display accordingly. +* Bug Fix: Gravatar Profile Widget: Allow basic HTML to be displayed. +* Bug Fix: Twitter Widget: Error handling fixes. +* Bug Fix: Sharing: Improved theme compatibility +* Bug Fix: JSON API: Fixed error when creating some posts in some versions of PHP. + += 1.9.2 = +Release Date: October 29, 2012 + +* Bug Fix: Only sync options on upgrade once. + += 1.9.1 = +Release Date: October 29, 2012 +Release Post: http://wp.me/p1moTy-iC + +* Enhancement: Notifications feature is enabled for logged-out users when the module is active & the toolbar is shown by another plugin. +* Bug Fix: Use proper CDN addresses to avoid SSL cert issues. +* Bug Fix: Prioritize syncing comments over deleting comments on WordPress.com. Fixes comment notifications marked as spam appearing to be trashed. + += 1.9 = +Release Date: October 26, 2012 +Release Post: http://wp.me/p1moTy-hC + +* Enhancement: Notifications: Display Notifications in the toolbar and support reply/moderation of comment notifications. +* Enhancement: Mobile Push Notifications: Added support for mobile push notifications of new comments for users that linked their accounts to WordPress.com accounts. +* Enhancement: JSON API: Allows applications to send API requests via WordPress.com (see [the docs](http://developer.wordpress.com/docs/api/) ) +* Enhancement: Sync: Modules (that require the data) sync full Post/Comment to ensure consistent data on WP.com (eg Stats) +* Enhancement: Sync: Improve syncing of site options to WP.com +* Enhancement: Sync: Sync attachment parents to WP.com +* Enhancement: Sync: Add signing of WP.com user ids for Jetpack Comments +* Enhancement: Sync: Mark and obfuscate private posts. +* Enhancement: Privacy: Default disable enhanced-distribution and json-api modules if site appears to be private. +* Enhancement: Custom CSS: allow applying Custom CSS to mobile theme. +* Enhancement: Sharing: On HTTPS pageloads, load as much of the sharing embeds as possible from HTTPS URLs. +* Enhancement: Contact Form: Overhaul of the contact form code to fix incompatibilites with other plugins. +* Bug Fix: Only allow users with manage_options permission to enable/disable modules +* Bug Fix: Custom CSS: allow '/' in media query units; e.g. (-o-min-device-pixel-ratio: 3/2) +* Bug Fix: Custom CSS: leave comments alone in CSS when editing but minify on the frontend +* Bug Fix: Sharing: Keep "more" pane open so Google+ Button isn't obscured +* Bug Fix: Carousel: Make sure the original size is used, even when it is exceedingly large. +* Bug Fix: Exclude iPad from Twitter on iPhone mobile browsing +* Bug Fix: Sync: On .org user role changes synchronize the change to .com +* Bug Fix: Contact Form: Fix a bug where some web hosts would reject mail from the contact form due to email address spoofing. + += 1.8.3 = +Release Date: October 23, 2012 + +* Bug Fix: Subscriptions: Fix a bug where subscriptions were not being sent from the blog. +* Bug Fix: Twitter: Fix a bug where the Twitter username was being saved as blank. +* Bug Fix: Fix a bug where Contact Form notification emails were not being sent. + += 1.8.2 = +Release Date: October 4, 2012 +Release Post: http://wp.me/p1moTy-gI + +* Bug Fix: Subscriptions: Fix a bug where subscriptions were not sent for posts and comments written by some authors. +* Bug Fix: Widgets: Fix CSS that was uglifying some themes (like P2). +* Bug Fix: Widgets: Improve Top Posts and Pages styling. +* Bug Fix: Custom CSS: Make the default "Welcome" message translatable. +* Bug Fix: Fix Lithuanian translation. + += 1.8.1 = +Release Date: September 28, 2012 +Release Post: http://wp.me/p1moTy-gx + +* Bug Fix: Stats: Fixed a bug preventing some users from viewing stats. +* Bug Fix: Mobile Theme: Fixed some disabled toolbar buttons. +* Bug Fix: Top Posts widget: Fixed a bug preventing the usage of the Top Posts widget. +* Bug Fix: Mobile Theme: Fixed a bug that broke some sites when the Subscriptions module was not enabled and the Mobile Theme module was enabled. +* Bug Fix: Mobile Theme: Made mobile app promos in the Mobile Theme footer opt-in. +* Bug Fix: Twitter Widget: A fix to prevent malware warnings. +* Bug Fix: Mobile Theme: Fixed a bug that caused errors for some users with custom header images. + += 1.8 = +Release Date: September 27, 2012 +Release Post: http://wp.me/p1moTy-fV + +* Enhancement: Mobile Theme: Automatically serve a slimmed down version of your site to users on mobile devices. +* Enhancement: Multiuser: Allow multiple users to link their accounts to WordPress.com accounts. +* Enhancement: Custom CSS: Added support for object-fit, object-position, transition, and filter properties. +* Enhancement: Twitter Widget: Added Follow button +* Enhancement: Widgets: Added Top Posts and Pages widget +* Enhancement: Mobile Push Notifications: Added support for mobile push notifications on new comments. +* Enhancement: VideoPress: Shortcodes now support the HD option, for default HD playback. +* Bug Fix: Twitter Widget: Fixed tweet permalinks in the Twitter widget +* Bug Fix: Custom CSS: @import rules and external images are no longer stripped out of custom CSS +* Bug Fix: Custom CSS: Fixed warnings and notices displayed in debug mode +* Bug Fix: Sharing: Fixed double-encoding of image URLs +* Bug Fix: Sharing: Fix Google +1 button HTML validation issues (again :)) +* Bug Fix: Gravatar Profile Widget: Reduce size of header margins + += 1.7 = +Release Date: August 23, 2012 +Release Post: http://wp.me/p1moTy-eq + +* Enhancement: CSS Editor: Customize your site's design without modifying your theme. +* Enhancement: Comments: Submit the comment within the iframe. No more full page load to jetpack.wordpress.com. +* Enhancement: Sharing: Share counts for Twitter, Facebook, LinkedIn +* Enhancement: Sharing: Improve styling +* Enhancement: Sharing: Add support for ReCaptcha +* Enhancement: Sharing: Better extensability through filters +* Enhancement: Widgets: Twitter: Attempt to reduce errors by storing a long lasting copy of the data. Thanks, kareldonk :) +* Regression Fix: Sharing: Properly store and display the sharing label option's default value. +* Bug Fix: Contact Form: remove worse-than-useless nonce. +* Bug Fix: Subscriptions: remove worse-than-useless nonce. +* Bug Fix: Sharing: Don't show sharing buttons twice on attachment pages. +* Bug Fix: Sharing: Increase width of Spanish Like button for Facebook. +* Bug Fix: Sharing: Use the correct URL to the throbber. +* Bug Fix: Stats: Fix notice about undefined variable $alt +* Bug Fix: Subscriptions: Make Subscriptions module obey the settings of the Settngs -> Discussion checkboxes for Follow Blog/Comments +* Bug Fix: Shortcodes: VideoPress: Compatibility with the latest version of VideoPress +* Bug Fix: Shortcodes: Audio: Include JS File for HTML5 audio player +* Bug Fix: Hovercards: Improve cache handling. +* Bug Fix: Widgets: Gravatar Profle: Correctly display service icons in edge cases. +* Bug Fix: Widgets: Gravatar Profle: Prevent ugly "flash" of too-large image when page first loads on some sites +* Bug Fix: Carousel: CSS Compatibility with more themes. + += 1.6.1 = +Release Date: August 4, 2012 + +* Bug Fix: Prevent Fatal error under certain conditions in sharing module +* Bug Fix: Add cachebuster to sharing.css +* Bug Fix: Disable via for Twitter until more robust code is in place + += 1.6 = +Release Date: August 2, 2012 +Release Post: http://wp.me/p1moTy-e0 + +* Enhancement: Carousel: Better image resolution selection based on available width/height. +* Enhancement: Carousel: Load image caption, metadata, comments, et alii when a slide is clicked to switch to instead of waiting. +* Enhancement: Carousel: Added a "Comment" button and handling to scroll to and focus on comment textarea. +* Enhancement: Widgets: Facebook Likebox now supports a height parameter and a better width parameter. +* Enhancement: Widgets: Better feedback when widgets are not set up properly. +* Enhancement: Shortcodes: Google Maps shortcode now supports percentages in the width. +* Enhancement: Shortcodes: Update Polldaddy shortcode for more efficient Javascript libraries. +* Enhancement: Shortcodes: Youtube shortcode now has playlist support. +* Enhancement: Add Gravatar Profile widget. +* Enhancement: Update Sharedaddy to latest version, including Pinterest support. +* Enhancement: Retinize Jetpack and much of WordPress. +* Bug Fix: Shortcodes: Fix Audio shortcode color parameter and rename encoding function. +* Bug Fix: Shortcodes: Don't output HTML 5 version of the Audio shortcode because of a bug with Google Reader. +* Bug Fix: Jetpack Comments: Don't overlead the addComments object if it doesn't exist. Fixes spacing issue with comment form. +* Bug Fix: Contact Form: If send_to_editor() exists, use it. Fixes an IE9 text area issue. + += 1.5 = +Release Date: July 31, 2012 +Release Post: http://wp.me/p1moTy-d7 + +* Enhancement: Add Gallery Carousel feature +* Note: the Carousel module bundles http://fgnass.github.com/spin.js/ (MIT license) + += 1.4.2 = +Release Date: June 20, 2012 + +* Bug Fix: Jetpack Comments: Add alternative Javascript event listener for Internet 8 users. +* Enhancement: Remove more PHP 4 backwards-compatible code (WordPress andJetpack only support PHP 5). +* Enhancement: Remove more WordPress 3.1 and under backwards-compatible code. + += 1.4.1 = +Release Date: June 15, 2012 + +* Bug Fix: Jetpack Comments / Subscriptions: Add checkboxes and logic control for the Subscription checkboxes. + += 1.4 = +Release Date: June 14, 2012 +Release Post: http://wp.me/p1moTy-cz + +* Enhancement: Add Jetpack Comments feature. +* Bug Fix: Sharing: Make the sharing_label translatable. +* Bug Fix: Sharing: Fixed the file type on the LinkedIn graphic. +* Bug Fix: Sharing: Fixes for the Faceboox Like button language locales. +* Bug Fix: Sharing: Updates for the "more" button when used with touch screen devices. +* Bug Fix: Sharing: Properly scope the More button so that multiple More buttons on a page behave properly. +* Bug Fix: Shortcodes: Update the YouTube and Audio shortcodes to better handle spaces in the URLs. +* Bug Fix: Shortcodes: Make the YouTube shortcode respect embed settings in Settings -> Media when appropriate. +* Bug Fix: Shortcodes: Removed the Slide.com shortcode; Slide.com no longer exists. +* Bug Fix: Shortcodes: Match both http and https links in the [googlemaps] shortcode. +* Bug Fix: After the Deadline: Code clean up and removal of inconsistencies. + += 1.3.4 = +Release Date: May 24, 2012 + +* Bug Fix: Revert changes to the top level menu that are causing problems. + += 1.3.3 = +Release Date: May 22, 2012 + +* Bug Fix: Fix notices caused by last update + += 1.3.2 = +Release Date: May 22, 2012 + +* Bug Fix: Fix Jetpack menu so that Akismet and VaultPress submenus show up. + += 1.3.1 = +Release Date: May 22, 2012 + +* Enhancement: Add a new widget, the Facebook Likebox +* Bug Fix: Sharing: Sharing buttons can now be used on custom post types. +* Bug Fix: Contact Forms: Make Contact Forms widget shortcode less aggressive about the shortcodes it converts. +* Bug Fix: Ensure contact forms are parsed correctly in text widgets. +* Bug Fix: Connection notices now only appear on the Dashboard and plugin page. +* Bug Fix: Connection notices are now dismissable if Jetpack is not network activated. +* Bug Fix: Subscriptions: Fix an issue that was causing errors with new BuddyPress forum posts. + += 1.3 = +Release Date: April 25, 2012 +Release Post: http://wp.me/p1moTy-bq + +* Enhancement: Add Contact Forms feature. Formerly Grunion Contact Forms. +* Bug Fix: Tweak YouTube autoembedder to catch more YouTube URLs. +* Bug Fix: Correctly load the Sharing CSS files. + += 1.2.4 = +Release Date: April 6, 2012 + +* Bug Fix: Fix rare bug with static front pages + += 1.2.3 = +Release Date: April 5, 2012 +Release Post: http://wp.me/p1moTy-b4 + +* Enhancement: Twitter Widget: Expand t.co URLs +* Bug Fix: Various PHP Notices. +* Bug Fix: WordPress Deprecated `add_contextual_help()` notices +* Bug Fix: Don't display unimportant DB errors when processing Jetpack nonces +* Bug Fix: Correctly sync data during certain MultiSite cases. +* Bug Fix: Stats: Allow sparkline img to load even when there is a DB upgrade. +* Bug Fix: Stats: Replace "loading title" with post title regardless of type and status. +* Bug Fix: Stats: Avoid edge case infinite redirect for `show_on_front=page` sites where the `home_url()` conatins uppercase letters. +* Bug Fix: Subscriptions: Don't send subscriptions if the feature is turned off in Jetpack. +* Bug Fix: Subscriptions: Fix pagination of subscribers. +* Bug Fix: Subscriptions: Sync data about categories/tags as well to improve subscription emails. +* Bug Fix: Subscriptions: Better styling for the subscription success message. +* Bug Fix: Shortcodes: Support for multiple Google Maps in one post. Support for all Google Maps URLs. +* Bug Fix: Shortcodes: Improved support for youtu.be URLs +* Bug Fix: Shortcodes: Improved Vimeo embeds. +* Bug Fix: Sharing: Switch to the 20px version of Google's +1 button for consistency. +* Bug Fix: Sharing: Fix Google +1 button HTML validation issues. +* Bug Fix: Sharing: Disable sharing buttons during preview. +* Bug Fix: Spelling and Grammar: Properly handle proofreading settings. +* Bug Fix: Spelling and Grammar: Don't prevent post save when proofreading service is unavailable. + += 1.2.2 = +Release Date: December 6, 2011 +Release Post: http://wp.me/p1moTy-ax + +* Bug Fix: Ensure expected modules get reactivated correctly during upgrade. +* Bug Fix: Don't send subscription request during spam comment submission. +* Bug Fix: Increased theme compatibility for subscriptions. +* Bug Fix: Remove reference to unused background image. + += 1.2.1 = +Release Date: November 18, 2011 +Release Post: http://wp.me/p1moTy-9H + +* Bug Fix: Ensure Site Stats menu item is accessible. +* Bug Fix: Fixed errors displayed during some upgrades. +* Bug Fix: Fix inaccurate new modules "bubble" in menu for some upgrades. +* Bug Fix: Fix VaultPress detection. +* Bug Fix: Fix link to http://jetpack.com/faq/ + += 1.2 = +Release Date: November 17, 2011 +Release Post: http://wp.me/p1moTy-8x + +* Enhancement: Add Subscriptions: Subscribe to site's posts and posts' comments. +* Enhancement: Add Google Maps shortcode. +* Enhancement: Add Image Widget. +* Enhancement: Add RSS Links Widget. +* Enhancement: Stats: More responsive stats dashboard. +* Enhancement: Shortcodes: Google Maps, VideoPress +* Enhancement: Sharing: Google+, LinkedIn +* Enhancement: Enhanced Distribution: Added Jetpack blogs to http://en.wordpress.com/firehose/ +* Bug Fix: Spelling and Grammar: WordPress 3.3 compatibility. +* Bug Fix: Translatable module names/descriptinos. +* Bug Fix: Correctly detect host's ability to make outgoing HTTPS requests. + += 1.1.3 = +Release Date: July 19, 2011 +Release Post: http://wp.me/p1moTy-90 + +* Bug Fix: Increase compatibility with WordPress 3.2's new `wp_remote_request()` API. +* Bug Fix: Increase compatibility with Admin Bar. +* Bug Fix: Stats: Improved performance when creating new posts. +* Bug Fix: Twitter Widget: Fix PHP Notice. +* Bug Fix: Sharedaddy: Fix PHP Warning. +* Enhancement: AtD: Add spellcheck button to Distraction Free Writing screen. +* Translations: Added: Bosnian, Danish, German, Finnish, Galician, Croatian, Indonesian, Macedonian, Norwegian (Bokmål), Russian, Slovak, Serbian, Swedish +* Translations: Updated: Spanish, French, Italian, Japanese, Brazilian Portuguese, Portuguese + += 1.1.2 = +Release Date: July 6, 2011 +Release Post: http://wp.me/p1moTy-8B + +* Bug Fix: Note, store, and keep fresh the time difference between the Jetpack site's host and the Jetpack servers at WordPress.com. Should fix all "timestamp is too old" errors. +* Bug Fix: Improve experience on hosts capable of making outgoing HTTPS requests but incapable of verifying SSL certificates. Fixes some "register_http_request_failed", "error setting certificate verify locations", and "error:14090086:lib(20):func(144):reason(134)" errors. +* Bug Fix: Better fallback when WordPress.com is experiencing problems. +* Bug Fix: It's Jetpack, not JetPack :) +* Bug Fix: Remove PHP Warnings/Notices. +* Bug Fix: AtD: JS based XSS bug. Props markjaquith. +* Bug Fix: AtD: Prevent stored configuration options from becoming corrupted. +* Bug Fix: Stats: Prevent missing old stats for some blogs. +* Bug Fix: Twitter Widget: Fix formatting of dates/times in PHP4. +* Bug Fix: Twitter Widget: Cache the response from Twitter to prevent "Twitter did not respond. Please wait a few minutes and refresh this page." errors. +* Enhancement: Slightly improved RTL experience. Jetpack 1.2 should include a much better fix. +* Enhancement: Sharedaddy: Improve localization for Facebook Like button. +* Enhancement: Gravatar Hovercards: Improved experience for Windows browsers. + += 1.1.1 = +Release Date: March 19, 2011 +Release Post: http://wp.me/p1moTy-8i + +* Bug Fix: Improve experience on hosts capable of making outgoing HTTPS requests but incapable of verifying SSL certificates. Fixes most "Your Jetpack has a glitch. Connecting this site with WordPress.com is not possible. This usually means your site is not publicly accessible (localhost)." errors. +* Bug Fix: Sharedaddy: Fatal error under PHP4. Disable on PHP4 hosts. +* Bug Fix: Stats: Fatal error under PHP4. Rewrite to be PHP4 compatible. +* Bug Fix: Stats: Fatal error on some sites modifying/removing core WordPress user roles. Add sanity check. +* Bug Fix: Stats: Replace debug output with error message in dashboard widget. +* Bug Fix: Stats: Rework hook priorities so that stats views are always counted even if a plugin (such as Paginated Comments) bails early on template_redirect. +* Bug Fix: Identify the module that connot be activated to fatal error during single module activation. +* Bug Fix: `glob()` is not always available. Use `opendir()`, `readdir()`, `closedir()`. +* Bug Fix: Send permalink options to Stats Server for improved per post permalink calculation. +* Bug Fix: Do not hide Screen Options and Help links during Jetpack call to connect. +* Bug Fix: Improve readablitiy of text. +* Bug Fix: AtD: Correctly store/display options. +* Enhancement: Output more informative error messages. +* Enhancement: Improve CSS styling. +* Enhancement: Stats: Query all post types and statuses when getting posts for stats reports. +* Enhancement: Improve performance of LaTeX URLs be using cookieless CDN. + += 1.1 = +Release Date: March 9, 2011 +Release post: http://wp.me/p1moTy-7R + +* Initial release diff --git a/plugins/jetpack/images/connect-plug.svg b/plugins/jetpack/images/connect-plug.svg index 94f2e60..7b6d0af 100644 --- a/plugins/jetpack/images/connect-plug.svg +++ b/plugins/jetpack/images/connect-plug.svg @@ -1,19 +1,19 @@ - - - - - - - - - + + + + + + + + + diff --git a/plugins/jetpack/images/connection-landing/long-clouds.svg b/plugins/jetpack/images/connection-landing/long-clouds.svg index e24fb8e..fc82f2b 100644 --- a/plugins/jetpack/images/connection-landing/long-clouds.svg +++ b/plugins/jetpack/images/connection-landing/long-clouds.svg @@ -1,38 +1,38 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/plugins/jetpack/images/connection-landing/stars-left.svg b/plugins/jetpack/images/connection-landing/stars-left.svg index ec15ca5..8bd5387 100644 --- a/plugins/jetpack/images/connection-landing/stars-left.svg +++ b/plugins/jetpack/images/connection-landing/stars-left.svg @@ -1,172 +1,172 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/jetpack/images/connection-landing/stars-right.svg b/plugins/jetpack/images/connection-landing/stars-right.svg index 540d011..96d862d 100644 --- a/plugins/jetpack/images/connection-landing/stars-right.svg +++ b/plugins/jetpack/images/connection-landing/stars-right.svg @@ -1,172 +1,172 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/jetpack/images/connection-landing/stat-bars.svg b/plugins/jetpack/images/connection-landing/stat-bars.svg index e05b283..d989a45 100644 --- a/plugins/jetpack/images/connection-landing/stat-bars.svg +++ b/plugins/jetpack/images/connection-landing/stat-bars.svg @@ -1,125 +1,125 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/jetpack/images/download-arrow.svg b/plugins/jetpack/images/download-arrow.svg index 511596f..dd6a440 100644 --- a/plugins/jetpack/images/download-arrow.svg +++ b/plugins/jetpack/images/download-arrow.svg @@ -1,10 +1,10 @@ - - - - - - - + + + + + + + diff --git a/plugins/jetpack/images/jetpack-logo.svg b/plugins/jetpack/images/jetpack-logo.svg index e494841..f6574e3 100644 --- a/plugins/jetpack/images/jetpack-logo.svg +++ b/plugins/jetpack/images/jetpack-logo.svg @@ -1,27 +1,27 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/plugins/jetpack/images/jetpack-protect-shield.svg b/plugins/jetpack/images/jetpack-protect-shield.svg index 9d89dea..9a4af07 100644 --- a/plugins/jetpack/images/jetpack-protect-shield.svg +++ b/plugins/jetpack/images/jetpack-protect-shield.svg @@ -1,30 +1,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/jetpack/images/new-badge.svg b/plugins/jetpack/images/new-badge.svg index 0a1aa61..01a1473 100644 --- a/plugins/jetpack/images/new-badge.svg +++ b/plugins/jetpack/images/new-badge.svg @@ -1,10 +1,10 @@ - - - - - - + + + + + + diff --git a/plugins/jetpack/images/rocketeer.svg b/plugins/jetpack/images/rocketeer.svg index 25bac60..49f7b51 100644 --- a/plugins/jetpack/images/rocketeer.svg +++ b/plugins/jetpack/images/rocketeer.svg @@ -1,14 +1,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/plugins/jetpack/images/the-cloud-sm.svg b/plugins/jetpack/images/the-cloud-sm.svg index e006252..a685f14 100644 --- a/plugins/jetpack/images/the-cloud-sm.svg +++ b/plugins/jetpack/images/the-cloud-sm.svg @@ -1,30 +1,30 @@ - - - - - - - + + + + + + + diff --git a/plugins/jetpack/images/the-cloud.svg b/plugins/jetpack/images/the-cloud.svg index 8cadb9e..c272ad2 100644 --- a/plugins/jetpack/images/the-cloud.svg +++ b/plugins/jetpack/images/the-cloud.svg @@ -1,16 +1,16 @@ - - - - - - - - + + + + + + + + diff --git a/plugins/jetpack/images/the-footcloud.svg b/plugins/jetpack/images/the-footcloud.svg index 3a83f65..308cb5e 100644 --- a/plugins/jetpack/images/the-footcloud.svg +++ b/plugins/jetpack/images/the-footcloud.svg @@ -1,9 +1,9 @@ - - - - - - + + + + + + diff --git a/plugins/jetpack/images/the-undercloud.svg b/plugins/jetpack/images/the-undercloud.svg index d581244..1433918 100644 --- a/plugins/jetpack/images/the-undercloud.svg +++ b/plugins/jetpack/images/the-undercloud.svg @@ -1,13 +1,13 @@ - - - - - - + + + + + + diff --git a/plugins/jetpack/modules/module-headings.php b/plugins/jetpack/modules/module-headings.php index 6dc2e8a..76451e0 100644 --- a/plugins/jetpack/modules/module-headings.php +++ b/plugins/jetpack/modules/module-headings.php @@ -1,308 +1,308 @@ - array( - 'name' => _x( 'Spelling and Grammar', 'Module Name', 'jetpack' ), - 'description' => _x( 'Check your spelling, style, and grammar with the After the Deadline proofreading service.', 'Module Description', 'jetpack' ), - ), + array( - 'name' => _x( 'Carousel', 'Module Name', 'jetpack' ), - 'description' => _x( 'Transform standard image galleries into full-screen slideshows.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Brings your photos and images to life as full-size, easily navigable galleries.', 'Jumpstart Description', 'jetpack' ), - ), - - 'comments' => array( - 'name' => _x( 'Comments', 'Module Name', 'jetpack' ), - 'description' => _x( 'Let readers comment with WordPress.com, Twitter, Facebook, or Google+ accounts.', 'Module Description', 'jetpack' ), - ), - - 'contact-form' => array( - 'name' => _x( 'Contact Form', 'Module Name', 'jetpack' ), - 'description' => _x( 'Insert a contact form anywhere on your site.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Adds a button to your post and page editors, allowing you to build simple forms to help visitors stay in touch.', 'Jumpstart Description', 'jetpack' ), - ), - - 'custom-content-types' => array( - 'name' => _x( 'Custom Content Types', 'Module Name', 'jetpack' ), - 'description' => _x( 'Organize and display different types of content on your site, separate from posts and pages.', 'Module Description', 'jetpack' ), - ), - - 'custom-css' => array( - 'name' => _x( 'Custom CSS', 'Module Name', 'jetpack' ), - 'description' => _x( 'Customize your site’s CSS without modifying your theme.', 'Module Description', 'jetpack' ), - ), - - 'enhanced-distribution' => array( - 'name' => _x( 'Enhanced Distribution', 'Module Name', 'jetpack' ), - 'description' => _x( 'Increase reach and traffic.', 'Module Description', 'jetpack' ), - ), - - 'gravatar-hovercards' => array( - 'name' => _x( 'Gravatar Hovercards', 'Module Name', 'jetpack' ), - 'description' => _x( 'Enable pop-up business cards over commenters’ Gravatars.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Let commenters link their profiles to their Gravatar accounts, making it easy for your visitors to learn more about your community.', 'Jumpstart Description', 'jetpack' ), - ), - - 'infinite-scroll' => array( - 'name' => _x( 'Infinite Scroll', 'Module Name', 'jetpack' ), - 'description' => _x( 'Add support for infinite scroll to your theme.', 'Module Description', 'jetpack' ), - ), - - 'json-api' => array( - 'name' => _x( 'JSON API', 'Module Name', 'jetpack' ), - 'description' => _x( 'Allow applications to securely access your content through the cloud.', 'Module Description', 'jetpack' ), - ), - - 'latex' => array( - 'name' => _x( 'Beautiful Math', 'Module Name', 'jetpack' ), - 'description' => _x( 'Use LaTeX markup language in posts and pages for complex equations and other geekery.', 'Module Description', 'jetpack' ), - ), - - 'likes' => array( - 'name' => _x( 'Likes', 'Module Name', 'jetpack' ), - 'description' => _x( 'Give visitors an easy way to show their appreciation for your content.', 'Module Description', 'jetpack' ), - ), - - 'manage' => array( - 'name' => _x( 'Manage', 'Module Name', 'jetpack' ), - 'description' => _x( 'Manage all your sites from a centralized place, https://wordpress.com/sites.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Helps you remotely manage plugins, turn on automated updates, and more from wordpress.com.', 'Jumpstart Description', 'jetpack' ), - ), - - 'markdown' => array( - 'name' => _x( 'Markdown', 'Module Name', 'jetpack' ), - 'description' => _x( 'Write posts or pages in plain-text Markdown syntax.', 'Module Description', 'jetpack' ), - ), - - 'minileven' => array( - 'name' => _x( 'Mobile Theme', 'Module Name', 'jetpack' ), - 'description' => _x( 'Optimize your site with a mobile-friendly theme for smartphones.', 'Module Description', 'jetpack' ), - ), - - 'monitor' => array( - 'name' => _x( 'Monitor', 'Module Name', 'jetpack' ), - 'description' => _x( 'Reports on site downtime.', 'Module Description', 'jetpack' ), - ), - - 'notes' => array( - 'name' => _x( 'Notifications', 'Module Name', 'jetpack' ), - 'description' => _x( 'Receive notification of site activity via the admin toolbar and your Mobile devices.', 'Module Description', 'jetpack' ), - ), - - 'omnisearch' => array( - 'name' => _x( 'Omnisearch', 'Module Name', 'jetpack' ), - 'description' => _x( 'Search your entire database from a single field in your Dashboard.', 'Module Description', 'jetpack' ), - ), - - 'photon' => array( - 'name' => _x( 'Photon', 'Module Name', 'jetpack' ), - 'description' => _x( 'Speed up images and photos.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Mirrors and serves your images from our free and fast image CDN, improving your site’s performance with no additional load on your servers.', 'Jumpstart Description', 'jetpack' ), - ), - - 'post-by-email' => array( - 'name' => _x( 'Post by Email', 'Module Name', 'jetpack' ), - 'description' => _x( 'Publish posts by email, using any device and email client.', 'Module Description', 'jetpack' ), - ), - - 'protect' => array( - 'name' => _x( 'Protect', 'Module Name', 'jetpack' ), - 'description' => _x( 'Prevent brute force attacks.', 'Module Description', 'jetpack' ), - ), - - 'publicize' => array( - 'name' => _x( 'Publicize', 'Module Name', 'jetpack' ), - 'description' => _x( 'Automatically promote content.', 'Module Description', 'jetpack' ), - ), - - 'related-posts' => array( - 'name' => _x( 'Related Posts', 'Module Name', 'jetpack' ), - 'description' => _x( 'Display similar content.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Keep visitors engaged on your blog by highlighting relevant and new content at the bottom of each published post.', 'Jumpstart Description', 'jetpack' ), - ), - - 'sharedaddy' => array( - 'name' => _x( 'Sharing', 'Module Name', 'jetpack' ), - 'description' => _x( 'Visitors can share your content.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Twitter, Facebook and Google+ buttons at the bottom of each post, making it easy for visitors to share your content.', 'Jumpstart Description', 'jetpack' ), - ), - - 'shortcodes' => array( - 'name' => _x( 'Shortcode Embeds', 'Module Name', 'jetpack' ), - 'description' => _x( 'Embed content from YouTube, Vimeo, SlideShare, and more, no coding necessary.', 'Module Description', 'jetpack' ), - ), - - 'shortlinks' => array( - 'name' => _x( 'WP.me Shortlinks', 'Module Name', 'jetpack' ), - 'description' => _x( 'Enable WP.me-powered shortlinks for all posts and pages.', 'Module Description', 'jetpack' ), - ), - - 'site-icon' => array( - 'name' => _x( 'Site Icon', 'Module Name', 'jetpack' ), - 'description' => _x( 'Add a site icon to your site.', 'Module Description', 'jetpack' ), - ), - - 'sitemaps' => array( - 'name' => _x( 'Sitemaps', 'Module Name', 'jetpack' ), - 'description' => _x( 'Creates sitemaps to allow your site to be easily indexed by search engines.', 'Module Description', 'jetpack' ), - ), - - 'sso' => array( - 'name' => _x( 'Single Sign On', 'Module Name', 'jetpack' ), - 'description' => _x( 'Secure user authentication.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Lets you log in to all your Jetpack-enabled sites with one click using your WordPress.com account.', 'Jumpstart Description', 'jetpack' ), - ), - - 'stats' => array( - 'name' => _x( 'Site Stats', 'Module Name', 'jetpack' ), - 'description' => _x( 'Collect traffic stats and insights.', 'Module Description', 'jetpack' ), - ), - - 'subscriptions' => array( - 'name' => _x( 'Subscriptions', 'Module Name', 'jetpack' ), - 'description' => _x( 'Allow users to subscribe to your posts and comments and receive notifications via email.', 'Module Description', 'jetpack' ), - 'recommended description' => _x( 'Give visitors two easy subscription options — while commenting, or via a separate email subscription widget you can display.', 'Jumpstart Description', 'jetpack' ), - ), - - 'tiled-gallery' => array( - 'name' => _x( 'Tiled Galleries', 'Module Name', 'jetpack' ), - 'description' => _x( 'Display your image galleries in a variety of sleek, graphic arrangements.', 'Module Description', 'jetpack' ), - ), - - 'vaultpress' => array( - 'name' => _x( 'Data Backups', 'Module Name', 'jetpack' ), - 'description' => _x( 'Daily or real-time backups.', 'Module Description', 'jetpack' ), - ), - - 'verification-tools' => array( - 'name' => _x( 'Site Verification', 'Module Name', 'jetpack' ), - 'description' => _x( 'Verify your site or domain with Google Search Console, Pinterest, and others.', 'Module Description', 'jetpack' ), - ), - - 'videopress' => array( - 'name' => _x( 'VideoPress', 'Module Name', 'jetpack' ), - 'description' => _x( 'Upload and embed videos right on your site. (Subscription required.)', 'Module Description', 'jetpack' ), - ), - - 'widget-visibility' => array( - 'name' => _x( 'Widget Visibility', 'Module Name', 'jetpack' ), - 'description' => _x( 'Specify which widgets appear on which pages of your site.', 'Module Description', 'jetpack' ), - ), - - 'widgets' => array( - 'name' => _x( 'Extra Sidebar Widgets', 'Module Name', 'jetpack' ), - 'description' => _x( 'Add images, Twitter streams, your site’s RSS links, and more to your sidebar.', 'Module Description', 'jetpack' ), - ), - ); - } - return $modules[ $key ]; -} -/** - * For a given module tag, return its translated version. - * - * @param string $key Module tag as is in each module heading. - * - * @return string +/** + * For a given module, return an array with translated name, description and recommended description. + * + * @param string $key Module file name without .php + * + * @return array */ -function jetpack_get_module_i18n_tag( $key ) { - static $module_tags; - if ( ! isset( $module_tags ) ) { - $module_tags = array( - // Modules with `Other` tag: - // - modules/contact-form.php - // - modules/notes.php - // - modules/site-icon.php - 'Other' =>_x( 'Other', 'Module Tag', 'jetpack' ), - - // Modules with `Writing` tag: - // - modules/after-the-deadline.php - // - modules/custom-content-types.php - // - modules/enhanced-distribution.php - // - modules/json-api.php - // - modules/latex.php - // - modules/markdown.php - // - modules/post-by-email.php - // - modules/shortcodes.php - 'Writing' =>_x( 'Writing', 'Module Tag', 'jetpack' ), - - // Modules with `Photos and Videos` tag: - // - modules/carousel.php - // - modules/photon.php - // - modules/shortcodes.php - // - modules/tiled-gallery.php - // - modules/videopress.php - 'Photos and Videos' =>_x( 'Photos and Videos', 'Module Tag', 'jetpack' ), - - // Modules with `Social` tag: - // - modules/comments.php - // - modules/gravatar-hovercards.php - // - modules/likes.php - // - modules/publicize.php - // - modules/sharedaddy.php - // - modules/shortcodes.php - // - modules/shortlinks.php - // - modules/subscriptions.php - // - modules/widgets.php - 'Social' =>_x( 'Social', 'Module Tag', 'jetpack' ), - - // Modules with `Appearance` tag: - // - modules/custom-css.php - // - modules/gravatar-hovercards.php - // - modules/infinite-scroll.php - // - modules/minileven.php - // - modules/photon.php - // - modules/shortcodes.php - // - modules/widget-visibility.php - // - modules/widgets.php - 'Appearance' =>_x( 'Appearance', 'Module Tag', 'jetpack' ), - - // Modules with `Developers` tag: - // - modules/json-api.php - // - modules/omnisearch.php - // - modules/sso.php - 'Developers' =>_x( 'Developers', 'Module Tag', 'jetpack' ), - - // Modules with `Centralized Management` tag: - // - modules/manage.php - 'Centralized Management' =>_x( 'Centralized Management', 'Module Tag', 'jetpack' ), - - // Modules with `Recommended` tag: - // - modules/manage.php - // - modules/minileven.php - // - modules/monitor.php - // - modules/photon.php - // - modules/protect.php - // - modules/publicize.php - // - modules/related-posts.php - // - modules/sharedaddy.php - // - modules/sitemaps.php - // - modules/stats.php - 'Recommended' =>_x( 'Recommended', 'Module Tag', 'jetpack' ), - - // Modules with `Mobile` tag: - // - modules/minileven.php - 'Mobile' =>_x( 'Mobile', 'Module Tag', 'jetpack' ), - - // Modules with `Traffic` tag: - // - modules/sitemaps.php - 'Traffic' =>_x( 'Traffic', 'Module Tag', 'jetpack' ), - - // Modules with `Site Stats` tag: - // - modules/stats.php - 'Site Stats' =>_x( 'Site Stats', 'Module Tag', 'jetpack' ), - ); - } - return $module_tags[ $key ]; +function jetpack_get_module_i18n( $key ) { + static $modules; + if ( ! isset( $modules ) ) { + $modules = array( + 'after-the-deadline' => array( + 'name' => _x( 'Spelling and Grammar', 'Module Name', 'jetpack' ), + 'description' => _x( 'Check your spelling, style, and grammar with the After the Deadline proofreading service.', 'Module Description', 'jetpack' ), + ), + + 'carousel' => array( + 'name' => _x( 'Carousel', 'Module Name', 'jetpack' ), + 'description' => _x( 'Transform standard image galleries into full-screen slideshows.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Brings your photos and images to life as full-size, easily navigable galleries.', 'Jumpstart Description', 'jetpack' ), + ), + + 'comments' => array( + 'name' => _x( 'Comments', 'Module Name', 'jetpack' ), + 'description' => _x( 'Let readers comment with WordPress.com, Twitter, Facebook, or Google+ accounts.', 'Module Description', 'jetpack' ), + ), + + 'contact-form' => array( + 'name' => _x( 'Contact Form', 'Module Name', 'jetpack' ), + 'description' => _x( 'Insert a contact form anywhere on your site.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Adds a button to your post and page editors, allowing you to build simple forms to help visitors stay in touch.', 'Jumpstart Description', 'jetpack' ), + ), + + 'custom-content-types' => array( + 'name' => _x( 'Custom Content Types', 'Module Name', 'jetpack' ), + 'description' => _x( 'Organize and display different types of content on your site, separate from posts and pages.', 'Module Description', 'jetpack' ), + ), + + 'custom-css' => array( + 'name' => _x( 'Custom CSS', 'Module Name', 'jetpack' ), + 'description' => _x( 'Customize your site’s CSS without modifying your theme.', 'Module Description', 'jetpack' ), + ), + + 'enhanced-distribution' => array( + 'name' => _x( 'Enhanced Distribution', 'Module Name', 'jetpack' ), + 'description' => _x( 'Increase reach and traffic.', 'Module Description', 'jetpack' ), + ), + + 'gravatar-hovercards' => array( + 'name' => _x( 'Gravatar Hovercards', 'Module Name', 'jetpack' ), + 'description' => _x( 'Enable pop-up business cards over commenters’ Gravatars.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Let commenters link their profiles to their Gravatar accounts, making it easy for your visitors to learn more about your community.', 'Jumpstart Description', 'jetpack' ), + ), + + 'infinite-scroll' => array( + 'name' => _x( 'Infinite Scroll', 'Module Name', 'jetpack' ), + 'description' => _x( 'Add support for infinite scroll to your theme.', 'Module Description', 'jetpack' ), + ), + + 'json-api' => array( + 'name' => _x( 'JSON API', 'Module Name', 'jetpack' ), + 'description' => _x( 'Allow applications to securely access your content through the cloud.', 'Module Description', 'jetpack' ), + ), + + 'latex' => array( + 'name' => _x( 'Beautiful Math', 'Module Name', 'jetpack' ), + 'description' => _x( 'Use LaTeX markup language in posts and pages for complex equations and other geekery.', 'Module Description', 'jetpack' ), + ), + + 'likes' => array( + 'name' => _x( 'Likes', 'Module Name', 'jetpack' ), + 'description' => _x( 'Give visitors an easy way to show their appreciation for your content.', 'Module Description', 'jetpack' ), + ), + + 'manage' => array( + 'name' => _x( 'Manage', 'Module Name', 'jetpack' ), + 'description' => _x( 'Manage all your sites from a centralized place, https://wordpress.com/sites.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Helps you remotely manage plugins, turn on automated updates, and more from wordpress.com.', 'Jumpstart Description', 'jetpack' ), + ), + + 'markdown' => array( + 'name' => _x( 'Markdown', 'Module Name', 'jetpack' ), + 'description' => _x( 'Write posts or pages in plain-text Markdown syntax.', 'Module Description', 'jetpack' ), + ), + + 'minileven' => array( + 'name' => _x( 'Mobile Theme', 'Module Name', 'jetpack' ), + 'description' => _x( 'Optimize your site with a mobile-friendly theme for smartphones.', 'Module Description', 'jetpack' ), + ), + + 'monitor' => array( + 'name' => _x( 'Monitor', 'Module Name', 'jetpack' ), + 'description' => _x( 'Reports on site downtime.', 'Module Description', 'jetpack' ), + ), + + 'notes' => array( + 'name' => _x( 'Notifications', 'Module Name', 'jetpack' ), + 'description' => _x( 'Receive notification of site activity via the admin toolbar and your Mobile devices.', 'Module Description', 'jetpack' ), + ), + + 'omnisearch' => array( + 'name' => _x( 'Omnisearch', 'Module Name', 'jetpack' ), + 'description' => _x( 'Search your entire database from a single field in your Dashboard.', 'Module Description', 'jetpack' ), + ), + + 'photon' => array( + 'name' => _x( 'Photon', 'Module Name', 'jetpack' ), + 'description' => _x( 'Speed up images and photos.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Mirrors and serves your images from our free and fast image CDN, improving your site’s performance with no additional load on your servers.', 'Jumpstart Description', 'jetpack' ), + ), + + 'post-by-email' => array( + 'name' => _x( 'Post by Email', 'Module Name', 'jetpack' ), + 'description' => _x( 'Publish posts by email, using any device and email client.', 'Module Description', 'jetpack' ), + ), + + 'protect' => array( + 'name' => _x( 'Protect', 'Module Name', 'jetpack' ), + 'description' => _x( 'Prevent brute force attacks.', 'Module Description', 'jetpack' ), + ), + + 'publicize' => array( + 'name' => _x( 'Publicize', 'Module Name', 'jetpack' ), + 'description' => _x( 'Automatically promote content.', 'Module Description', 'jetpack' ), + ), + + 'related-posts' => array( + 'name' => _x( 'Related Posts', 'Module Name', 'jetpack' ), + 'description' => _x( 'Display similar content.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Keep visitors engaged on your blog by highlighting relevant and new content at the bottom of each published post.', 'Jumpstart Description', 'jetpack' ), + ), + + 'sharedaddy' => array( + 'name' => _x( 'Sharing', 'Module Name', 'jetpack' ), + 'description' => _x( 'Visitors can share your content.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Twitter, Facebook and Google+ buttons at the bottom of each post, making it easy for visitors to share your content.', 'Jumpstart Description', 'jetpack' ), + ), + + 'shortcodes' => array( + 'name' => _x( 'Shortcode Embeds', 'Module Name', 'jetpack' ), + 'description' => _x( 'Embed content from YouTube, Vimeo, SlideShare, and more, no coding necessary.', 'Module Description', 'jetpack' ), + ), + + 'shortlinks' => array( + 'name' => _x( 'WP.me Shortlinks', 'Module Name', 'jetpack' ), + 'description' => _x( 'Enable WP.me-powered shortlinks for all posts and pages.', 'Module Description', 'jetpack' ), + ), + + 'site-icon' => array( + 'name' => _x( 'Site Icon', 'Module Name', 'jetpack' ), + 'description' => _x( 'Add a site icon to your site.', 'Module Description', 'jetpack' ), + ), + + 'sitemaps' => array( + 'name' => _x( 'Sitemaps', 'Module Name', 'jetpack' ), + 'description' => _x( 'Creates sitemaps to allow your site to be easily indexed by search engines.', 'Module Description', 'jetpack' ), + ), + + 'sso' => array( + 'name' => _x( 'Single Sign On', 'Module Name', 'jetpack' ), + 'description' => _x( 'Secure user authentication.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Lets you log in to all your Jetpack-enabled sites with one click using your WordPress.com account.', 'Jumpstart Description', 'jetpack' ), + ), + + 'stats' => array( + 'name' => _x( 'Site Stats', 'Module Name', 'jetpack' ), + 'description' => _x( 'Collect traffic stats and insights.', 'Module Description', 'jetpack' ), + ), + + 'subscriptions' => array( + 'name' => _x( 'Subscriptions', 'Module Name', 'jetpack' ), + 'description' => _x( 'Allow users to subscribe to your posts and comments and receive notifications via email.', 'Module Description', 'jetpack' ), + 'recommended description' => _x( 'Give visitors two easy subscription options — while commenting, or via a separate email subscription widget you can display.', 'Jumpstart Description', 'jetpack' ), + ), + + 'tiled-gallery' => array( + 'name' => _x( 'Tiled Galleries', 'Module Name', 'jetpack' ), + 'description' => _x( 'Display your image galleries in a variety of sleek, graphic arrangements.', 'Module Description', 'jetpack' ), + ), + + 'vaultpress' => array( + 'name' => _x( 'Data Backups', 'Module Name', 'jetpack' ), + 'description' => _x( 'Daily or real-time backups.', 'Module Description', 'jetpack' ), + ), + + 'verification-tools' => array( + 'name' => _x( 'Site Verification', 'Module Name', 'jetpack' ), + 'description' => _x( 'Verify your site or domain with Google Search Console, Pinterest, and others.', 'Module Description', 'jetpack' ), + ), + + 'videopress' => array( + 'name' => _x( 'VideoPress', 'Module Name', 'jetpack' ), + 'description' => _x( 'Upload and embed videos right on your site. (Subscription required.)', 'Module Description', 'jetpack' ), + ), + + 'widget-visibility' => array( + 'name' => _x( 'Widget Visibility', 'Module Name', 'jetpack' ), + 'description' => _x( 'Specify which widgets appear on which pages of your site.', 'Module Description', 'jetpack' ), + ), + + 'widgets' => array( + 'name' => _x( 'Extra Sidebar Widgets', 'Module Name', 'jetpack' ), + 'description' => _x( 'Add images, Twitter streams, your site’s RSS links, and more to your sidebar.', 'Module Description', 'jetpack' ), + ), + ); + } + return $modules[ $key ]; +} +/** + * For a given module tag, return its translated version. + * + * @param string $key Module tag as is in each module heading. + * + * @return string + */ +function jetpack_get_module_i18n_tag( $key ) { + static $module_tags; + if ( ! isset( $module_tags ) ) { + $module_tags = array( + // Modules with `Other` tag: + // - modules/contact-form.php + // - modules/notes.php + // - modules/site-icon.php + 'Other' =>_x( 'Other', 'Module Tag', 'jetpack' ), + + // Modules with `Writing` tag: + // - modules/after-the-deadline.php + // - modules/custom-content-types.php + // - modules/enhanced-distribution.php + // - modules/json-api.php + // - modules/latex.php + // - modules/markdown.php + // - modules/post-by-email.php + // - modules/shortcodes.php + 'Writing' =>_x( 'Writing', 'Module Tag', 'jetpack' ), + + // Modules with `Photos and Videos` tag: + // - modules/carousel.php + // - modules/photon.php + // - modules/shortcodes.php + // - modules/tiled-gallery.php + // - modules/videopress.php + 'Photos and Videos' =>_x( 'Photos and Videos', 'Module Tag', 'jetpack' ), + + // Modules with `Social` tag: + // - modules/comments.php + // - modules/gravatar-hovercards.php + // - modules/likes.php + // - modules/publicize.php + // - modules/sharedaddy.php + // - modules/shortcodes.php + // - modules/shortlinks.php + // - modules/subscriptions.php + // - modules/widgets.php + 'Social' =>_x( 'Social', 'Module Tag', 'jetpack' ), + + // Modules with `Appearance` tag: + // - modules/custom-css.php + // - modules/gravatar-hovercards.php + // - modules/infinite-scroll.php + // - modules/minileven.php + // - modules/photon.php + // - modules/shortcodes.php + // - modules/widget-visibility.php + // - modules/widgets.php + 'Appearance' =>_x( 'Appearance', 'Module Tag', 'jetpack' ), + + // Modules with `Developers` tag: + // - modules/json-api.php + // - modules/omnisearch.php + // - modules/sso.php + 'Developers' =>_x( 'Developers', 'Module Tag', 'jetpack' ), + + // Modules with `Centralized Management` tag: + // - modules/manage.php + 'Centralized Management' =>_x( 'Centralized Management', 'Module Tag', 'jetpack' ), + + // Modules with `Recommended` tag: + // - modules/manage.php + // - modules/minileven.php + // - modules/monitor.php + // - modules/photon.php + // - modules/protect.php + // - modules/publicize.php + // - modules/related-posts.php + // - modules/sharedaddy.php + // - modules/sitemaps.php + // - modules/stats.php + 'Recommended' =>_x( 'Recommended', 'Module Tag', 'jetpack' ), + + // Modules with `Mobile` tag: + // - modules/minileven.php + 'Mobile' =>_x( 'Mobile', 'Module Tag', 'jetpack' ), + + // Modules with `Traffic` tag: + // - modules/sitemaps.php + 'Traffic' =>_x( 'Traffic', 'Module Tag', 'jetpack' ), + + // Modules with `Site Stats` tag: + // - modules/stats.php + 'Site Stats' =>_x( 'Site Stats', 'Module Tag', 'jetpack' ), + ); + } + return $module_tags[ $key ]; } \ No newline at end of file diff --git a/plugins/jetpack/modules/sitemaps/sitemap-xsl.php b/plugins/jetpack/modules/sitemaps/sitemap-xsl.php index 906f11f..8f9cc0f 100644 --- a/plugins/jetpack/modules/sitemaps/sitemap-xsl.php +++ b/plugins/jetpack/modules/sitemaps/sitemap-xsl.php @@ -1,144 +1,144 @@ - - - - - - - ' . esc_html( ent2ncr( __( 'XML Sitemap', 'jetpack' ) ) ) . ' - - - - -
-

' . esc_html( ent2ncr( __( 'XML Sitemap', 'jetpack' ) ) ) . '

-

' . wp_kses( sprintf( ent2ncr( __( 'This is an XML Sitemap generated by Jetpack, meant to be consumed by search engines like Google or Bing.', 'jetpack' ), 'http://jetpack.com/', 'https://www.google.com', 'https://www.bing.com/' ), array( 'a' => array( 'href' => true, 'title' => true ) ) ) ) . '

-

' . wp_kses( sprintf( ent2ncr( __( 'You can find more information on XML sitemaps at sitemaps.org', 'jetpack' ), 'http://sitemaps.org' ), array( 'a' => array( 'href' => true, 'title' => true ) ) ) ) . '

-
-
- - - - '; -if ( empty( $type ) ) : -$xsl .= ' - '; -endif; -$xsl .= ' - - - - - - - odd - - - - '; -if ( empty( $type ) ) : -$xsl .= ' - '; -endif; -$xsl .= ' - -
' . esc_html( ent2ncr( __( 'URL', 'jetpack' ) ) ) . '' . esc_html( ent2ncr( __( 'Images', 'jetpack' ) ) ) . '' . esc_html( ent2ncr( __( 'Change Frequency', 'jetpack' ) ) ) . '' . esc_html( ent2ncr( __( 'Last Updated', 'jetpack' ) ) ) . '
- - - - - - - - - - - - -
-
- - - -
-
'; + + + + + + + ' . esc_html( ent2ncr( __( 'XML Sitemap', 'jetpack' ) ) ) . ' + + + + +
+

' . esc_html( ent2ncr( __( 'XML Sitemap', 'jetpack' ) ) ) . '

+

' . wp_kses( sprintf( ent2ncr( __( 'This is an XML Sitemap generated by Jetpack, meant to be consumed by search engines like Google or Bing.', 'jetpack' ), 'http://jetpack.com/', 'https://www.google.com', 'https://www.bing.com/' ), array( 'a' => array( 'href' => true, 'title' => true ) ) ) ) . '

+

' . wp_kses( sprintf( ent2ncr( __( 'You can find more information on XML sitemaps at sitemaps.org', 'jetpack' ), 'http://sitemaps.org' ), array( 'a' => array( 'href' => true, 'title' => true ) ) ) ) . '

+
+
+ + + + '; +if ( empty( $type ) ) : +$xsl .= ' + '; +endif; +$xsl .= ' + + + + + + + odd + + + + '; +if ( empty( $type ) ) : +$xsl .= ' + '; +endif; +$xsl .= ' + +
' . esc_html( ent2ncr( __( 'URL', 'jetpack' ) ) ) . '' . esc_html( ent2ncr( __( 'Images', 'jetpack' ) ) ) . '' . esc_html( ent2ncr( __( 'Change Frequency', 'jetpack' ) ) ) . '' . esc_html( ent2ncr( __( 'Last Updated', 'jetpack' ) ) ) . '
+ + + + + + + + + + + + +
+
+ + + +
+
'; diff --git a/plugins/jetpack/readme.txt b/plugins/jetpack/readme.txt index b7e821b..739a162 100644 --- a/plugins/jetpack/readme.txt +++ b/plugins/jetpack/readme.txt @@ -1,514 +1,514 @@ -=== Jetpack by WordPress.com === -Contributors: automattic, adamkheckler, aduth, akirk, allendav, alternatekev, andy, apeatling, azaozz, batmoo, barry, beaulebens, blobaugh, cainm, cfinke, chaselivingston, chellycat, csonnek, danielbachhuber, davoraltman, daniloercoli, designsimply, dllh, drawmyface, dsmart, dzver, ebinnion, eliorivero, enej, eoigal, ethitter, gcorne, georgestephanis, gibrown, goldsounds, hew, hugobaeta, hypertextranch, iammattthomas, iandunn, jacobshere, jblz, jeherve, jenhooks, jenia, jkudish, jmdodd, Joen, johnjamesjacoby, jshreve, koke, kraftbj, lamdayap, lancewillett, lschuyler, macmanx, martinremy, matt, matveb, mattwiebe, maverick3x6, mcsf, mdawaffe, michael-arestad, migueluy, mikeyarce, mkaz, nancythanki, nickmomrik, obenland, pento, professor44, ryancowles, richardmuscat, richardmtl, roccotripaldi, samhotchkiss, sdquirk, stephdau, tmoorewp, Viper007Bond, westi, yoavf, zinigor -Tags: WordPress.com, jet pack, comments, contact, gallery, performance, sharing, security, shortcodes, stats, subscriptions, widgets -Stable tag: 4.0.4 -Requires at least: 4.4 -Tested up to: 4.5.2 - -Increase your traffic, view your stats, speed up your site, and protect yourself from hackers with Jetpack. - -== Description == - -Jetpack simplifies managing WordPress sites by giving you visitor stats, security services, speeding up images, and helping you get more traffic. Jetpack is a free plugin. - -= Traffic Growth & Insights = -Jetpack tells you how many visits your site gets and helps you **get more traffic** with tools like Related Posts, Publicize, Enhanced Distribution, and Sharing. - -= Security = -Jetpack **protects your site** against brute force attacks and unauthorised logins. We also monitor your site for downtime and keep your plugins updated. - -= Image Performance = -Jetpack automatically **optimizes and speeds up** images using the global WordPress.com content delivery network. This saves you hosting costs by reducing bandwidth. - -= Centralized Management = -With Jetpack comes a **centralized dashboard** on WordPress.com. Manage plugins and menus, publish posts, and view enhanced site stats for all of your sites. - -= A few more things that our users love = -Jetpack includes other features that help you customize your site including Custom CSS, Contact Forms, Galleries and Carousels, Notifications and Subscriptions, Configurable Widgets, and [many more](https://jetpack.com/features). - -= Dedicated Support = -We have an entire team of happiness engineers ready to help you. Ask your questions in the support forum, or [contact us directly](https://jetpack.com/contact-support). - -= Contributing to Jetpack = - -Jetpack is open-source and we actively encourage community contributions: whether it's a compliment, bug report, code, or an idea we welcome it with open arms! [Learn about contributing](https://jetpack.com/contribute) or consider [joining our beta program](https://jetpack.com/beta). - -== Installation == - -[Install Jetpack from our site](https://jetpack.com/install?from=wporg) by typing in your site address. - -Alternatively install Jetpack via the plugin directory, or by uploading the files manually to your server. After activating Jetpack, connect to WordPress.com to enable the Jetpack features. - -If you need additional help [read our detailed instructions (including a video walkthrough)](http://jetpack.com/support/installing-jetpack/). - - -== Frequently Asked Questions == - -= Is Jetpack free? = - -Yes! The core features of Jetpack are and always will be free. Jetpack also integrates with paid services like Akismet (anti-spam), VaultPress (backups), and VideoPress (video hosting) but these are not required for Jetpack to function. - -= Why do I need a WordPress.com account? = - -Many of our core features (like Photon, Stats, and Protect) make use of the WordPress.com cloud. For this to happen Jetpack requires a (free) WordPress.com account. If you don't have one already you can easily create one during Jetpack's connection process. - -= I already have a WordPress account, but it's not working. What's going on? = - -A WordPress.com account is different to the one you use to log into your self-hosted WordPress. If you can log into http://wordpress.com then you already have a WordPress.com account. If you can't, you can easily create one during Jetpack's connection process. - -= How do I view my stats? = - -Once you've installed Jetpack your stats will be available via "Site Stats" which appears in the Jetpack menu (under your Dashboard menu within WordPress). - -= How do I contribute to Jetpack? = - -There are opportunities for developers at all levels to contribute. [Learn more about contributing to Jetpack](https://jetpack.com/contribute) or consider [joining our beta program](https://jetpack.com/beta). - - -== Screenshots == - -1. Jetpack Dashboard. -2. Site Stats. -3. Plugin Bulk Management. -4. Publicize. -5. Related Posts. - -== Changelog == - -= 4.0.4 = -Release date: June 20th, 2016 -Release Post: http://wp.me/p1moTy-3eT - -Security: - -* Post By Email: Added an additional layer of security to prevent unauthorized changes to Post By Email settings. -* Likes: Fixed an XSS vulnerability in the Likes module. -* REST API/Contact Form: We've eliminated unauthenticated access to Feedback posts. - -Feature Improvements: - -* Customizing Protect: We've increased Protect’s response time and added a new filter, `jetpack_protect_connect_timeout`, reducing the likelihood of seeing the fall back form. -* Connection Process: Your site url and icon are displayed on the Jetpack connection screens to help improve communication. -* Jetpack for Multisite: It’s now easier to manage your Jetpack connections on the network admin screen. -* Photon Responsive Image Improvements: We’re now auto-generating new scrset options, improving how images served from Photon are handled. -* Developing on Kinsta: A new constant has been added to improve developing with Jetpack on a staging environment hosted with Kinsta. - -Jetpack UI Improvements: - -* Better Access to Our Support Team: We wanted to make it easier for you to get help so we added a contact form in the admin that links directly to our Jetpack Support Team. - -Improved Compatibility: - -* We’ve stopped adding Open Graph Meta tags if you’re using the SEO Framework plugin. -* Having both GlotPress and Jetpack active at the same time was causing errors, we’ve eliminated them. - -Bug Fixes: - -* Fixed the handling of special characters like ampersands in Carousel Titles and Descriptions. -* When visitors tried to view a Carousel image with a hash in the URL, a JavaScript error would occur; we’ve fixed that. -* Jetpack Comment form fields now use the default language you’ve set for WordPress, previously the verbiage was always in English. -* Custom CSS wasn’t handling slashes and quotes properly; we’ve squashed that bug. -* There were some rare cases where PHP notices were popping up when a Contact Form was submitted. These instances have been identified and eliminated. -* We’ve replaced a bit of code with a Jetpack native function to fix a bug that was breaking things during an API request for available updates. -* We accidentally removed the ability for Open Graph to select images from slideshows, it’s up and running again. -* There was an issue where Open Graph meta tags weren’t being set when your homepage is a “Static Front Page”, it’s working again. -* In rare cases when developers were customizing Photon they were seeing a PHP notice when arguments were passed as a string rather than an array. This has been fixed. -* We’ve fixed an issue where Protect’s backup math form wasn’t showing on custom frontend login forms. -* When setting up WooCommerce you might have seen a Related Posts notice which didn’t belong. We’ve eliminated them. -* If you’ve been using our sharing tool with unofficial sharing buttons you might have noticed your sharing numbers were missing. They’re now back. -* In unique situations where special characters were used in sitemap stylesheets an error would occur; that has been remedied. -* We’ve fixed a problem with mismatching HTML tags in our Spelling and Grammar feature. -* We’ve ensured that the `jetpack_disable_twitter_cards` filter actually removes Twitter cards. -* We’ve fixed some JavaScript errors that would crop up if you were editing a custom-post-type post that didn’t support the core media editor — say that 10 times fast. -* We had some JavaScript errors when you were using the customizer to modify widgets. They are no longer with us. - -= 4.0.3 = -Release date: May 26th, 2016 -Release Post: http://wp.me/p1moTy-3hm - -* Important security update. Please upgrade immediately. - -= 4.0.2 = -Release date: April 21st, 2016 - -Bug Fix: - -* Addresses an issue where Jetpack 4.0 caused a fatal error on sites with specific configurations. - -= 4.0 = -Release date: April 20th, 2016 -Release Post: http://wp.me/p1moTy-3dL - -Performance Enhancements: - -* Protect: the routine that verifies your site is protected from brute-force attacks got some love and is more efficient. -* Contact Forms: cleaning the database of spam form submission records is more efficient. - -Feature Improvements: - -* VideoPress: edit your VideoPress shortcode in the editor with a fancy new modal options window. -* Custom Content Types are now classier: a new CSS class on Testimonial featured images — has-testimonial-thumbnail — allows you to customize Jetpack custom post types as you see fit. -* Sharing: social icons are now placed under the "add to cart” singular product views in WooCommerce, making it easier for customers to share your products on social media. -* Theme Tools: search engines will now have an easier time knowing what page they are on, and how that page relates to the other pages in your site hierarchy with improved schema.org microdata for breadcrumbs. -* Widget Visibility: now you can select widgets and when to show or hide them right from custom post type single and archive views. - -Jetpack UI Improvements: - -* What’s in it for me? We’ve done a better job explaining the benefits of Jetpack and connecting it to WordPress.com. -* Shortcodes: handy links to shortcode documentation convey the types of media you can quickly and safely embed. -* Widgets: As of WordPress 4.5, Jetpack widgets now refresh in the customizer without making you refresh the entire page. Live previews, yes indeed. - -Bug Fixes: - -* Comments: we fixed a mistake where a comment subscription checkbox appeared on custom post types — despite the fact you couldn’t actually subscribe to those types of comments. Our bad. -* Contact Forms: we fixed a bug where the telephone field (which can only be added manually) rendered incorrectly — breaking some forms in the process. -* General: we blocked direct access to the Jetpack_IXR_Client class which caused fatal PHP errors in some server setups. -* Shortcodes: we removed the frameborder attribute in the YouTube embed code. It was deprecated in HTML 5. -* Unminified responsive-videos.min.js in order to address a false positive virus alert in ClamAV. Expect it to be re-minified in 4.0.3 once we resolve the issue with ClamAV. - -= 3.9.6 = -Release date: March 31st, 2016 -Release Post: http://wp.me/p1moTy-3bz - -Bug fix: Shortcodes: fixed incorrect Vimeo embed logic. - -= 3.9.5 = -Release date: March 31st, 2016 -Release Post: http://wp.me/p1moTy-3bz - -This release features several WordPress 4.5 compatibility changes that make several Jetpack features work properly in the Customizer view. Big thanks to @westonruter for contributing the code! - -Other enhancements and bug fixes: - -* Contact Form: no longer calling the datepicker method if it's not available. -* SSO: settings checkboxes now honor filters and constants that restrict certain sign-in modes. -* Shortcodes: fixed a problem with Gist fetching. -* Shortcodes: fixed invalid HTML5 markup in YouTube embed code. -* Shortcodes: made the Vimeo links work properly in case of multiple mixed uses in one post. - -= 3.9.4 = -Release date: March 10th, 2016 -Release post: http://wp.me/p1moTy-396 - -Bug fix: Shortcodes: Addresses an issue with embedded Vimeo content - -= 3.9.3 = -Release date: Mar 9th, 2016 -Release post: http://wp.me/p1moTy-396 - -Featured: - -* Site Logo now supports Custom Logo - a theme tool to be introduced in WordPress 4.5. - -Enhancements: - -* Carousel: Made the full size image URL use a Photon URL if enabled. -* Comments: Removed an unnecessary redirect by always connecting via HTTPS. -* General: Added new actions that fire before automatic updates. -* Infinite Scroll: Introduced a later filter for settings. -* Infinite Scroll: Removed code that is now redundant due to WordPress Core. -* Markdown: Removed deprecated markup from the output. -* Publicize: Improved handling of featured images in posts. -* Shortcodes: Added houzz.com support. -* Sitemaps: Added a language attribute to the news sitemap. -* Sitemaps: Improved the image retrieval mechanism for posts. -* Widgets: Added new filters in the Top Posts Widget code. -* Widgets: Cleaned up the CSS for the Subscription widget. - -Bug Fixes: - -* Comments: No longer reloading the page on clicking the reply button. -* Contact Forms: Fixed a fatal error on missing metadata. -* Contact Forms: Fixed message formatting for plaintext email clients. -* Shortcodes: Fixed dimensions of Vimeo embeds in certain cases. -* Shortcodes: Fixed warnings and allowed shorter style Vimeo embeds. -* Shortcodes: Removed alignment markup from feeds for YouTube embeds. -* Sitemaps: Made URLs display properly according to the permalink structure. -* Stats: Fixed non-XHTML-valid markup. -* Widgets: No longer showing errors when adding new instances of the Display Post Widget. - -= 3.9.2 = -Release date: Feb 25th, 2016 -Release post: http://wp.me/p1moTy-2Ei - -Maintenance and Security Release - -Featured: - -* Beautiful Math: fix XSS vulnerability when parsing LaTeX markup within HTML elements. -* Contact Form: do not save private site credentials in post meta. Thanks to @visualdatasolutions. - -Enhancements: - -* Contact Info: Added two hooks for adding arbitrary information to the widget. -* Development: Added new possibilities for REST API debugging. -* Embeds: Added Codepen embeds support. -* Embeds: Added Sketchfab embeds support. -* I18n: Added support for translation packages for the Finnish language. -* Markdown: Added a filter to enable skipping processing of developer supplied patterns. -* Related Posts: Added a filter to change heading markup. -* Staging: Added a constant to force staging mode. -* Staging: Added a notice to make staging mode more obvious. -* Top Posts Widget: Added a new `[jetpack_top_posts_widget]` shortcode. - -Bug Fixes: - -* Custom Post Types: Nova: Fixed a JavaScript bug on adding multiple items. -* Embeds: Allowing embeds from Instagram with a www in an URL. -* General: Fixed untranslated module names on the Settings screen. -* General: Improved module descriptions and fixed misleading or broken links in descriptions. -* General: No more notices on module deprecation on older installations. -* General: Only showing one prompt to enable Photon when uploading several new images. -* Multisite: Fixed a problem with site lists for older WordPress installations. -* OpenGraph: Fixed a bug to properly fallback to a WordPress Site Icon image. -* Photon: Improve performance for images over a secure connection. -* Photon: No longer including links from data attributes. -* Publicize: Fixed problems for en_AU and en_CA locales with Facebook. -* Related Posts: Fixed a notice on certain requests. -* Site Logo: It's no longer possible to choose a non-image. -* Widget Visibility: No longer confusing page IDs and titles in certain cases. - -= 3.9.1 = -Release date: Jan 21st, 2016 - -Bug Fixes: - -* General: Addresses a namespacing issue which was causing conflicts on some hosting providers. -* Sitemaps: Added MSM-Sitemap to the list of plugins which, if installed, will prevent Jetpack Sitemaps from being used - -= 3.9 = -Release date: Jan 20th, 2016 -Release Post: http://wp.me/p1moTy-29R - -Featured: - -* New sharing button: let users share your content using Skype. -* New "Social Menu" theme tool that uses Genericons to display Social Links. -* Sitemap support for better search engine indexing. - -Enhancements: - -* Contact Form: Added a new filter that allows you to change the "Required" text. -* General: Hidden archived sites in multisite site list. -* General: Removed several function calls that would be deprecated in WordPress 4.5. -* Infinite Scroll: Added a new filter to check if Infinite Scroll has been triggered. -* Likes: Added a conditional to ensure WordPress 4.5 compatibility. -* Photon: Improved compatibility with responsive images feature added in WordPress 4.4. -* Photon: Now enabled by default on sites using HTTPS. -* REST API: Extended the ability to manage users from WordPress.com. -* REST API: Increased the performance of the plugin update endpoint. -* Responsive Videos: Centering videos when they are wrapped in a centered paragraph. -* Sharing: Added a new filter to customize the default OpenGraph description. -* Shortcodes: Added Wistia oEmbed support. -* Shortcodes: Bandcamp: Added support for new attributes for tracks approved by artists. -* Shortcodes: Improved Medium path format recognition. -* Slideshow: Improved compatibility with older IE versions. -* Staging: Improved staging environment detection. -* Widgets: Added "width" option to the Facebook Page widget. -* Widgets: Added size parameters to tags in Top Posts to avoid warnings. -* Widgets: Introduced major performance and stability improvements to the Display Posts Widget. -* Widgets: Refactored to remove deprecated code patterns. - -Bug Fixes: - -* AtD: Fixed replacing emojis with images in the text editor in Chrome. -* AtD: Made pre tags be excluded from spell-checking. -* CPT: Not registering Nova if it is already registered. -* Carousel: Fixed a bug where full size images were not always served by Photon. -* Carousel: Reverted a change that broke direct link to carousel image. -* Contact Form: Fixed a CSV export bug with multiple choice questions. -* Contact Form: Fixed notices when creating feedback entries without a contact form. -* General: Fixed a scrolling bug on modal window closing. -* Infinite Scroll: Disabled in the Customizer when previewing a non-active theme. -* Publicize: Fixed notices appearing with bbPress or BuddyPress installed. -* Publicize: Showing options only to users that can change them. -* Related Posts: Fixed incorrect URLs generated for posts. -* Responsive Videos: Fixed warnings in debug mode. -* Shortcodes: Bandcamp: Fixed a problem with large track IDs. -* Shortcodes: Fixed a problem with dynamic Gist embeds. -* Stats: Fixed dashboard widget resize problem. -* Widgets: Added a fallback to English US when a locale isn't supported by Facebook. -* Widgets: Fixed layout for Twenty Sixteen. - -= 3.8.2 = -Release date: Dec 17th, 2015 -Release post: http://wp.me/p1moTy-26v - -Jetpack 3.8.2 is here to squash a few annoying bugs. - -Bug Fixes: - -* Photon: Fixed a bug where some custom thumbnail image sizes weren't being sized properly. -* Shortcodes: Fixed an incompatibility with how WordPress renders the YouTube shortcode. -* Shortcodes: Tightened up security in the Wufoo shortcode. -* Image Widget: Now shows the caption. -* Fixed typos in inline docs. -* Very minor fixes to: Carousel, Publicize, Google+, and Infinite Scroll. - -= 3.8.1 = -Release date: Dec 1st, 2015 -Release post: http://wp.me/p1moTy-23V - -Jetpack 3.8.1 is here and is fully compatible with WordPress 4.4. - -Featured: - -* Photon + Responsive Images FTW. -* Fully compatible with Twenty Sixteen. -* More accessibility enhancements. -* Dropped some weight by optimizing Jetpack's plugin images. - -Enhancements: - -* Comments: filter to allow disabling comments per post type. - -Bug Fixes: - -* Carousel: Stop page from scrolling to top when Carousel is closed. -* Carousel: Browser compatibility fixes with older version of IE. -* Markdown: Fixed a bug that would strip markdown when saving in "Quick Edit" mode. -* Single Sign On: Fixed login always redirecting to the admin dashboard. -* Subscriptions: Filter to allow per-post emails fixed for use in themes. - -= 3.8.0 = -Release date: Nov 4th, 2015 -Release post: http://wp.me/p1moTy-1VN - -We're happy to introduce Jetpack 3.8, which has significant contributions from the Jetpack community. Read more about it here: http://wp.me/p1moTy-1VN - -Feature enhancements: - -* New Google+ Badge Widget. Display your profile, page, or community Google+ badge. -* New twitch.tv shortcode embeds. Display a Twitch.tv stream in your posts. -* Accessibility enhancements. -* A handful of new filters to allow further customization of Jetpack. - -Other enhancements: - -* Carousel: Added support to retrieve image dimensions from an image url. -* Carousel: Simpler algorithm to detect shutter speeds. -* Contact Form: New "Checkbox with Multiple Items" field available in the Contact Form. -* Contact Form: Allow pre-filling form fields with URL parameters. -* Contact Form: Better styling of the emailed form responses. -* Performance: Replaced some custom-built functions with core's native functions. -* Related Posts: New filter to add post classes to post's container class. -* Sharing: New filter to choose if sharing meta box should be shown. -* Sharing: New filter to allow sharing button markup to be editable. -* Sharing: New filter to allow you to specify a custom Facebook app ID. -* Social Media Icons Widget: Added option for YouTube username as well as Channel ID. -* Social Media Icons Widget: Added Google+ icon. -* Social Media Icons Widget: New filter to allow you to add your own social media icons and links. -* Subscriptions: Better errors to your visitors if their subscription sign-up fails. -* Subscriptions: Removed "widget" class from Subs shortcode form. - - -Bug fixes: - -* Carousel: Fixed browser back/forward button behavior. -* Contact Form: Allow the email field to be set to empty when building form in post editor. -* Facebook Likebox Widget: Fixed an issue where some languages were not translating. -* Facebook Likebox Widget: Return a language when none found. -* General: Fixed some minor styling issues in the Jetpack admin areas. -* General: Add missing parameter to the_title filter call. -* General: Prevent scrolling of body when the Jetpack admin modals are opened. -* General: Update doc to reflect that Open Graph filter jetpack_enable_opengraph has been deprecated in favor of jetpack_enable_open_graph. -* Infinite Scroll: Fixed an error that sometimes occurred that would stop posts from loading. -* JSON API: Fixed some undefined notices when publishing a post with the API. -* Open Graph: Fixed bug where facebook description content was sometimes being polluted by a filter. -* Sharing: Use full SSL Pinterest url instead of protocol relative. -* Sharing: Fixed plus signs appearing in tweets shared from iOS. -* Shortcodes: Prefer HTTPS for video embeds to avoid mixed content warnings. -* Subscriptions Widget: Fix HTML Validation error. -* Theme Tools: Check oEmbeds for the presence of a video before adding the responsive videos filter. -* Tiled Galleries: Add image alt attribute if there is a title set. This was breaking some screen reader functionality. - -= 3.7.2 = -Release date: September 29th, 2015 -Release Post: http://wp.me/p1moTy-1LB - -* Bug Fix: REST API: Fixed an error when saving drafts and publishing posts - -= 3.7.1 = -Release date: September 28th, 2015 -Release Post: http://wp.me/p1moTy-1LB - -* Enhancement: General: Added inline documentation for various filters and functions -* Enhancement: General: Added custom capabilities for module management on multi-site installs -* Enhancement: General: Cleaned up old changelog entries from readme -* Enhancement: General: Cleaned up unused i18n textdomains -* Enhancement: General: Updated the new settings page to look better in various translations -* Enhancement: REST API: Added new endpoints to manage users -* Enhancement: Sharing: Updated the Google logo -* Bug Fix: Carousel: Page scroll no longer disappears after closing the carousel -* Bug Fix: Contact Form: Fields are sent and displayed in the correct order -* Bug Fix: Contact Form: No longer showing a notice on AJAX actions in feedback lists -* Bug Fix: Contact Form: Made using more than two notification emails possible -* Bug Fix: Contact Form: Mitigate a potential stored XSS vulnerability. Thanks to Marc-Alexandre Montpas (Sucuri) -* Bug Fix: General: Mitigate a potential information disclosure. Thanks to Jaime Delgado Horna -* Bug Fix: General: Fixed a locale error in the notifications popout -* Bug Fix: General: Fixed a possible fatal error in the client area -* Bug Fix: General: Fixed compatibility issues with certain use cases -* Bug Fix: General: Disabled connection warnings for multisites with domain mapping -* Bug Fix: General: Updated translations for correct link display in admin notices -* Bug Fix: REST API: Fixed a fatal error in one of the endpoints -* Bug Fix: Sharing: Fixed OpenGraph tags for Instagram embeds -* Bug Fix: Sharing: Fixed compatibility issues with bbPress -* Bug Fix: Widget Visibility: Fixed a fatal error in case of a missing tag - -= 3.7.0 = -Release date: September 9th, 2015 -Release Post: http://wp.me/p1moTy-1JB - -Feature Enhancements: - -* New admin page interface to easily configure Jetpack -* Added staging site support for testing a connected Jetpack site - -Additional changes: - -* Enhancement: CLI: Added a possibility to change all options with confirmation for some of them -* Enhancement: Gallery: Added filters to allow new gallery types to be declared -* Enhancement: General: Added inline documentation for actions, filters, etc. -* Enhancement: General: Changed class variable declarations keyword from var to public -* Enhancement: General: Made the Settings page module toggle buttons more accessible -* Enhancement: General: The admin bar now loads new notifications popout -* Enhancement: General: Renamed some modules to avoid redundant prefixes -* Enhancement: General: Switched to the WordPress Core's spinner image -* Enhancement: General: Updated the bot list -* Enhancement: Manage: Added the ability to activate a network-wide plugin on a single site from WordPress.com -* Enhancement: Photon: Added a way to check image URLs against custom domains -* Enhancement: Photon: Added prompts on the media upload page telling the user about Photon -* Enhancement: Publicize: Added width and height values to OpenGraph tags for default images -* Enhancement: Related Posts: Added a filter to allow disabling nofollow -* Enhancement: REST API: Added new API endpoints to extend API functionality -* Enhancement: REST API: Added new fields to existing API endpoints -* Enhancement: Sharing: Added a possibility to opt-out of sharing for a single post -* Enhancement: Sharing: Added bbPress support -* Enhancement: Sharing: Added more configuration to the Likes modal -* Enhancement: Sharing: Made the reddit button open a new tab -* Enhancement: Sharing: Removed unused files -* Enhancement: Shortcodes: Added auto embed option inside comments -* Enhancement: Shortcodes: Added autohide parameter to the YouTube shortcode -* Enhancement: Subscriptions: added an action that triggers at the end of the subscription process -* Enhancement: VideoPress: Videos are now embedded using a new player -* Enhancement: Widget Visibility: Added parent page logic -* Enhancement: Widget Visibility: Added support for split terms -* Enhancement: Widgets: Added actions to the Social Media widget -* Enhancement: Widgets: Switched the Display Posts widget to the new API version -* Bug Fix: General: Fixed scrolling to top after modal window closing -* Bug Fix: Infinite Scroll: Added a check for cases when output buffering is disabled -* Bug Fix: Infinite Scroll: Added translation to the copyright message -* Bug Fix: Manage: Fixed automatic update synchronization on WordPress multisite network admin -* Bug Fix: Manage: Redirects back to WordPress.com are allowed from the customizer view -* Bug Fix: Media: Fixed duplicate images bug in the Media Extractor -* Bug Fix: Publicize: Made it possible to remove previously set message -* Bug Fix: Sharing: Added a thumbnail image to OpenGraph tags on pages with DailyMotion embeds -* Bug Fix: Sharing: Fixed Twitter Cards tags escaping -* Bug Fix: Sharing: Made OpenGraph tags for title and description use proper punctuation -* Bug Fix: Sharing: Made sure Likes can be disabled on the front page -* Bug Fix: Shortcodes: Fixed Facebook embeds by placing the script in the footer -* Bug Fix: Shortcodes: Fixed PollDaddy shortcode issues over SSL connections -* Bug Fix: Shortcodes: Made responsive video wrappers only wrap video embeds -* Bug Fix: Shortcodes: Made SoundCloud accept percents for dimensions -* Bug Fix: Social Links: Fixed a possible conflict with another class -* Bug Fix: Stats: Made sure the Stats URL is always escaped properly +=== Jetpack by WordPress.com === +Contributors: automattic, adamkheckler, aduth, akirk, allendav, alternatekev, andy, apeatling, azaozz, batmoo, barry, beaulebens, blobaugh, cainm, cfinke, chaselivingston, chellycat, csonnek, danielbachhuber, davoraltman, daniloercoli, designsimply, dllh, drawmyface, dsmart, dzver, ebinnion, eliorivero, enej, eoigal, ethitter, gcorne, georgestephanis, gibrown, goldsounds, hew, hugobaeta, hypertextranch, iammattthomas, iandunn, jacobshere, jblz, jeherve, jenhooks, jenia, jkudish, jmdodd, Joen, johnjamesjacoby, jshreve, koke, kraftbj, lamdayap, lancewillett, lschuyler, macmanx, martinremy, matt, matveb, mattwiebe, maverick3x6, mcsf, mdawaffe, michael-arestad, migueluy, mikeyarce, mkaz, nancythanki, nickmomrik, obenland, pento, professor44, ryancowles, richardmuscat, richardmtl, roccotripaldi, samhotchkiss, sdquirk, stephdau, tmoorewp, Viper007Bond, westi, yoavf, zinigor +Tags: WordPress.com, jet pack, comments, contact, gallery, performance, sharing, security, shortcodes, stats, subscriptions, widgets +Stable tag: 4.0.4 +Requires at least: 4.4 +Tested up to: 4.5.2 + +Increase your traffic, view your stats, speed up your site, and protect yourself from hackers with Jetpack. + +== Description == + +Jetpack simplifies managing WordPress sites by giving you visitor stats, security services, speeding up images, and helping you get more traffic. Jetpack is a free plugin. + += Traffic Growth & Insights = +Jetpack tells you how many visits your site gets and helps you **get more traffic** with tools like Related Posts, Publicize, Enhanced Distribution, and Sharing. + += Security = +Jetpack **protects your site** against brute force attacks and unauthorised logins. We also monitor your site for downtime and keep your plugins updated. + += Image Performance = +Jetpack automatically **optimizes and speeds up** images using the global WordPress.com content delivery network. This saves you hosting costs by reducing bandwidth. + += Centralized Management = +With Jetpack comes a **centralized dashboard** on WordPress.com. Manage plugins and menus, publish posts, and view enhanced site stats for all of your sites. + += A few more things that our users love = +Jetpack includes other features that help you customize your site including Custom CSS, Contact Forms, Galleries and Carousels, Notifications and Subscriptions, Configurable Widgets, and [many more](https://jetpack.com/features). + += Dedicated Support = +We have an entire team of happiness engineers ready to help you. Ask your questions in the support forum, or [contact us directly](https://jetpack.com/contact-support). + += Contributing to Jetpack = + +Jetpack is open-source and we actively encourage community contributions: whether it's a compliment, bug report, code, or an idea we welcome it with open arms! [Learn about contributing](https://jetpack.com/contribute) or consider [joining our beta program](https://jetpack.com/beta). + +== Installation == + +[Install Jetpack from our site](https://jetpack.com/install?from=wporg) by typing in your site address. + +Alternatively install Jetpack via the plugin directory, or by uploading the files manually to your server. After activating Jetpack, connect to WordPress.com to enable the Jetpack features. + +If you need additional help [read our detailed instructions (including a video walkthrough)](http://jetpack.com/support/installing-jetpack/). + + +== Frequently Asked Questions == + += Is Jetpack free? = + +Yes! The core features of Jetpack are and always will be free. Jetpack also integrates with paid services like Akismet (anti-spam), VaultPress (backups), and VideoPress (video hosting) but these are not required for Jetpack to function. + += Why do I need a WordPress.com account? = + +Many of our core features (like Photon, Stats, and Protect) make use of the WordPress.com cloud. For this to happen Jetpack requires a (free) WordPress.com account. If you don't have one already you can easily create one during Jetpack's connection process. + += I already have a WordPress account, but it's not working. What's going on? = + +A WordPress.com account is different to the one you use to log into your self-hosted WordPress. If you can log into http://wordpress.com then you already have a WordPress.com account. If you can't, you can easily create one during Jetpack's connection process. + += How do I view my stats? = + +Once you've installed Jetpack your stats will be available via "Site Stats" which appears in the Jetpack menu (under your Dashboard menu within WordPress). + += How do I contribute to Jetpack? = + +There are opportunities for developers at all levels to contribute. [Learn more about contributing to Jetpack](https://jetpack.com/contribute) or consider [joining our beta program](https://jetpack.com/beta). + + +== Screenshots == + +1. Jetpack Dashboard. +2. Site Stats. +3. Plugin Bulk Management. +4. Publicize. +5. Related Posts. + +== Changelog == + += 4.0.4 = +Release date: June 20th, 2016 +Release Post: http://wp.me/p1moTy-3eT + +Security: + +* Post By Email: Added an additional layer of security to prevent unauthorized changes to Post By Email settings. +* Likes: Fixed an XSS vulnerability in the Likes module. +* REST API/Contact Form: We've eliminated unauthenticated access to Feedback posts. + +Feature Improvements: + +* Customizing Protect: We've increased Protect’s response time and added a new filter, `jetpack_protect_connect_timeout`, reducing the likelihood of seeing the fall back form. +* Connection Process: Your site url and icon are displayed on the Jetpack connection screens to help improve communication. +* Jetpack for Multisite: It’s now easier to manage your Jetpack connections on the network admin screen. +* Photon Responsive Image Improvements: We’re now auto-generating new scrset options, improving how images served from Photon are handled. +* Developing on Kinsta: A new constant has been added to improve developing with Jetpack on a staging environment hosted with Kinsta. + +Jetpack UI Improvements: + +* Better Access to Our Support Team: We wanted to make it easier for you to get help so we added a contact form in the admin that links directly to our Jetpack Support Team. + +Improved Compatibility: + +* We’ve stopped adding Open Graph Meta tags if you’re using the SEO Framework plugin. +* Having both GlotPress and Jetpack active at the same time was causing errors, we’ve eliminated them. + +Bug Fixes: + +* Fixed the handling of special characters like ampersands in Carousel Titles and Descriptions. +* When visitors tried to view a Carousel image with a hash in the URL, a JavaScript error would occur; we’ve fixed that. +* Jetpack Comment form fields now use the default language you’ve set for WordPress, previously the verbiage was always in English. +* Custom CSS wasn’t handling slashes and quotes properly; we’ve squashed that bug. +* There were some rare cases where PHP notices were popping up when a Contact Form was submitted. These instances have been identified and eliminated. +* We’ve replaced a bit of code with a Jetpack native function to fix a bug that was breaking things during an API request for available updates. +* We accidentally removed the ability for Open Graph to select images from slideshows, it’s up and running again. +* There was an issue where Open Graph meta tags weren’t being set when your homepage is a “Static Front Page”, it’s working again. +* In rare cases when developers were customizing Photon they were seeing a PHP notice when arguments were passed as a string rather than an array. This has been fixed. +* We’ve fixed an issue where Protect’s backup math form wasn’t showing on custom frontend login forms. +* When setting up WooCommerce you might have seen a Related Posts notice which didn’t belong. We’ve eliminated them. +* If you’ve been using our sharing tool with unofficial sharing buttons you might have noticed your sharing numbers were missing. They’re now back. +* In unique situations where special characters were used in sitemap stylesheets an error would occur; that has been remedied. +* We’ve fixed a problem with mismatching HTML tags in our Spelling and Grammar feature. +* We’ve ensured that the `jetpack_disable_twitter_cards` filter actually removes Twitter cards. +* We’ve fixed some JavaScript errors that would crop up if you were editing a custom-post-type post that didn’t support the core media editor — say that 10 times fast. +* We had some JavaScript errors when you were using the customizer to modify widgets. They are no longer with us. + += 4.0.3 = +Release date: May 26th, 2016 +Release Post: http://wp.me/p1moTy-3hm + +* Important security update. Please upgrade immediately. + += 4.0.2 = +Release date: April 21st, 2016 + +Bug Fix: + +* Addresses an issue where Jetpack 4.0 caused a fatal error on sites with specific configurations. + += 4.0 = +Release date: April 20th, 2016 +Release Post: http://wp.me/p1moTy-3dL + +Performance Enhancements: + +* Protect: the routine that verifies your site is protected from brute-force attacks got some love and is more efficient. +* Contact Forms: cleaning the database of spam form submission records is more efficient. + +Feature Improvements: + +* VideoPress: edit your VideoPress shortcode in the editor with a fancy new modal options window. +* Custom Content Types are now classier: a new CSS class on Testimonial featured images — has-testimonial-thumbnail — allows you to customize Jetpack custom post types as you see fit. +* Sharing: social icons are now placed under the "add to cart” singular product views in WooCommerce, making it easier for customers to share your products on social media. +* Theme Tools: search engines will now have an easier time knowing what page they are on, and how that page relates to the other pages in your site hierarchy with improved schema.org microdata for breadcrumbs. +* Widget Visibility: now you can select widgets and when to show or hide them right from custom post type single and archive views. + +Jetpack UI Improvements: + +* What’s in it for me? We’ve done a better job explaining the benefits of Jetpack and connecting it to WordPress.com. +* Shortcodes: handy links to shortcode documentation convey the types of media you can quickly and safely embed. +* Widgets: As of WordPress 4.5, Jetpack widgets now refresh in the customizer without making you refresh the entire page. Live previews, yes indeed. + +Bug Fixes: + +* Comments: we fixed a mistake where a comment subscription checkbox appeared on custom post types — despite the fact you couldn’t actually subscribe to those types of comments. Our bad. +* Contact Forms: we fixed a bug where the telephone field (which can only be added manually) rendered incorrectly — breaking some forms in the process. +* General: we blocked direct access to the Jetpack_IXR_Client class which caused fatal PHP errors in some server setups. +* Shortcodes: we removed the frameborder attribute in the YouTube embed code. It was deprecated in HTML 5. +* Unminified responsive-videos.min.js in order to address a false positive virus alert in ClamAV. Expect it to be re-minified in 4.0.3 once we resolve the issue with ClamAV. + += 3.9.6 = +Release date: March 31st, 2016 +Release Post: http://wp.me/p1moTy-3bz + +Bug fix: Shortcodes: fixed incorrect Vimeo embed logic. + += 3.9.5 = +Release date: March 31st, 2016 +Release Post: http://wp.me/p1moTy-3bz + +This release features several WordPress 4.5 compatibility changes that make several Jetpack features work properly in the Customizer view. Big thanks to @westonruter for contributing the code! + +Other enhancements and bug fixes: + +* Contact Form: no longer calling the datepicker method if it's not available. +* SSO: settings checkboxes now honor filters and constants that restrict certain sign-in modes. +* Shortcodes: fixed a problem with Gist fetching. +* Shortcodes: fixed invalid HTML5 markup in YouTube embed code. +* Shortcodes: made the Vimeo links work properly in case of multiple mixed uses in one post. + += 3.9.4 = +Release date: March 10th, 2016 +Release post: http://wp.me/p1moTy-396 + +Bug fix: Shortcodes: Addresses an issue with embedded Vimeo content + += 3.9.3 = +Release date: Mar 9th, 2016 +Release post: http://wp.me/p1moTy-396 + +Featured: + +* Site Logo now supports Custom Logo - a theme tool to be introduced in WordPress 4.5. + +Enhancements: + +* Carousel: Made the full size image URL use a Photon URL if enabled. +* Comments: Removed an unnecessary redirect by always connecting via HTTPS. +* General: Added new actions that fire before automatic updates. +* Infinite Scroll: Introduced a later filter for settings. +* Infinite Scroll: Removed code that is now redundant due to WordPress Core. +* Markdown: Removed deprecated markup from the output. +* Publicize: Improved handling of featured images in posts. +* Shortcodes: Added houzz.com support. +* Sitemaps: Added a language attribute to the news sitemap. +* Sitemaps: Improved the image retrieval mechanism for posts. +* Widgets: Added new filters in the Top Posts Widget code. +* Widgets: Cleaned up the CSS for the Subscription widget. + +Bug Fixes: + +* Comments: No longer reloading the page on clicking the reply button. +* Contact Forms: Fixed a fatal error on missing metadata. +* Contact Forms: Fixed message formatting for plaintext email clients. +* Shortcodes: Fixed dimensions of Vimeo embeds in certain cases. +* Shortcodes: Fixed warnings and allowed shorter style Vimeo embeds. +* Shortcodes: Removed alignment markup from feeds for YouTube embeds. +* Sitemaps: Made URLs display properly according to the permalink structure. +* Stats: Fixed non-XHTML-valid markup. +* Widgets: No longer showing errors when adding new instances of the Display Post Widget. + += 3.9.2 = +Release date: Feb 25th, 2016 +Release post: http://wp.me/p1moTy-2Ei + +Maintenance and Security Release + +Featured: + +* Beautiful Math: fix XSS vulnerability when parsing LaTeX markup within HTML elements. +* Contact Form: do not save private site credentials in post meta. Thanks to @visualdatasolutions. + +Enhancements: + +* Contact Info: Added two hooks for adding arbitrary information to the widget. +* Development: Added new possibilities for REST API debugging. +* Embeds: Added Codepen embeds support. +* Embeds: Added Sketchfab embeds support. +* I18n: Added support for translation packages for the Finnish language. +* Markdown: Added a filter to enable skipping processing of developer supplied patterns. +* Related Posts: Added a filter to change heading markup. +* Staging: Added a constant to force staging mode. +* Staging: Added a notice to make staging mode more obvious. +* Top Posts Widget: Added a new `[jetpack_top_posts_widget]` shortcode. + +Bug Fixes: + +* Custom Post Types: Nova: Fixed a JavaScript bug on adding multiple items. +* Embeds: Allowing embeds from Instagram with a www in an URL. +* General: Fixed untranslated module names on the Settings screen. +* General: Improved module descriptions and fixed misleading or broken links in descriptions. +* General: No more notices on module deprecation on older installations. +* General: Only showing one prompt to enable Photon when uploading several new images. +* Multisite: Fixed a problem with site lists for older WordPress installations. +* OpenGraph: Fixed a bug to properly fallback to a WordPress Site Icon image. +* Photon: Improve performance for images over a secure connection. +* Photon: No longer including links from data attributes. +* Publicize: Fixed problems for en_AU and en_CA locales with Facebook. +* Related Posts: Fixed a notice on certain requests. +* Site Logo: It's no longer possible to choose a non-image. +* Widget Visibility: No longer confusing page IDs and titles in certain cases. + += 3.9.1 = +Release date: Jan 21st, 2016 + +Bug Fixes: + +* General: Addresses a namespacing issue which was causing conflicts on some hosting providers. +* Sitemaps: Added MSM-Sitemap to the list of plugins which, if installed, will prevent Jetpack Sitemaps from being used + += 3.9 = +Release date: Jan 20th, 2016 +Release Post: http://wp.me/p1moTy-29R + +Featured: + +* New sharing button: let users share your content using Skype. +* New "Social Menu" theme tool that uses Genericons to display Social Links. +* Sitemap support for better search engine indexing. + +Enhancements: + +* Contact Form: Added a new filter that allows you to change the "Required" text. +* General: Hidden archived sites in multisite site list. +* General: Removed several function calls that would be deprecated in WordPress 4.5. +* Infinite Scroll: Added a new filter to check if Infinite Scroll has been triggered. +* Likes: Added a conditional to ensure WordPress 4.5 compatibility. +* Photon: Improved compatibility with responsive images feature added in WordPress 4.4. +* Photon: Now enabled by default on sites using HTTPS. +* REST API: Extended the ability to manage users from WordPress.com. +* REST API: Increased the performance of the plugin update endpoint. +* Responsive Videos: Centering videos when they are wrapped in a centered paragraph. +* Sharing: Added a new filter to customize the default OpenGraph description. +* Shortcodes: Added Wistia oEmbed support. +* Shortcodes: Bandcamp: Added support for new attributes for tracks approved by artists. +* Shortcodes: Improved Medium path format recognition. +* Slideshow: Improved compatibility with older IE versions. +* Staging: Improved staging environment detection. +* Widgets: Added "width" option to the Facebook Page widget. +* Widgets: Added size parameters to tags in Top Posts to avoid warnings. +* Widgets: Introduced major performance and stability improvements to the Display Posts Widget. +* Widgets: Refactored to remove deprecated code patterns. + +Bug Fixes: + +* AtD: Fixed replacing emojis with images in the text editor in Chrome. +* AtD: Made pre tags be excluded from spell-checking. +* CPT: Not registering Nova if it is already registered. +* Carousel: Fixed a bug where full size images were not always served by Photon. +* Carousel: Reverted a change that broke direct link to carousel image. +* Contact Form: Fixed a CSV export bug with multiple choice questions. +* Contact Form: Fixed notices when creating feedback entries without a contact form. +* General: Fixed a scrolling bug on modal window closing. +* Infinite Scroll: Disabled in the Customizer when previewing a non-active theme. +* Publicize: Fixed notices appearing with bbPress or BuddyPress installed. +* Publicize: Showing options only to users that can change them. +* Related Posts: Fixed incorrect URLs generated for posts. +* Responsive Videos: Fixed warnings in debug mode. +* Shortcodes: Bandcamp: Fixed a problem with large track IDs. +* Shortcodes: Fixed a problem with dynamic Gist embeds. +* Stats: Fixed dashboard widget resize problem. +* Widgets: Added a fallback to English US when a locale isn't supported by Facebook. +* Widgets: Fixed layout for Twenty Sixteen. + += 3.8.2 = +Release date: Dec 17th, 2015 +Release post: http://wp.me/p1moTy-26v + +Jetpack 3.8.2 is here to squash a few annoying bugs. + +Bug Fixes: + +* Photon: Fixed a bug where some custom thumbnail image sizes weren't being sized properly. +* Shortcodes: Fixed an incompatibility with how WordPress renders the YouTube shortcode. +* Shortcodes: Tightened up security in the Wufoo shortcode. +* Image Widget: Now shows the caption. +* Fixed typos in inline docs. +* Very minor fixes to: Carousel, Publicize, Google+, and Infinite Scroll. + += 3.8.1 = +Release date: Dec 1st, 2015 +Release post: http://wp.me/p1moTy-23V + +Jetpack 3.8.1 is here and is fully compatible with WordPress 4.4. + +Featured: + +* Photon + Responsive Images FTW. +* Fully compatible with Twenty Sixteen. +* More accessibility enhancements. +* Dropped some weight by optimizing Jetpack's plugin images. + +Enhancements: + +* Comments: filter to allow disabling comments per post type. + +Bug Fixes: + +* Carousel: Stop page from scrolling to top when Carousel is closed. +* Carousel: Browser compatibility fixes with older version of IE. +* Markdown: Fixed a bug that would strip markdown when saving in "Quick Edit" mode. +* Single Sign On: Fixed login always redirecting to the admin dashboard. +* Subscriptions: Filter to allow per-post emails fixed for use in themes. + += 3.8.0 = +Release date: Nov 4th, 2015 +Release post: http://wp.me/p1moTy-1VN + +We're happy to introduce Jetpack 3.8, which has significant contributions from the Jetpack community. Read more about it here: http://wp.me/p1moTy-1VN + +Feature enhancements: + +* New Google+ Badge Widget. Display your profile, page, or community Google+ badge. +* New twitch.tv shortcode embeds. Display a Twitch.tv stream in your posts. +* Accessibility enhancements. +* A handful of new filters to allow further customization of Jetpack. + +Other enhancements: + +* Carousel: Added support to retrieve image dimensions from an image url. +* Carousel: Simpler algorithm to detect shutter speeds. +* Contact Form: New "Checkbox with Multiple Items" field available in the Contact Form. +* Contact Form: Allow pre-filling form fields with URL parameters. +* Contact Form: Better styling of the emailed form responses. +* Performance: Replaced some custom-built functions with core's native functions. +* Related Posts: New filter to add post classes to post's container class. +* Sharing: New filter to choose if sharing meta box should be shown. +* Sharing: New filter to allow sharing button markup to be editable. +* Sharing: New filter to allow you to specify a custom Facebook app ID. +* Social Media Icons Widget: Added option for YouTube username as well as Channel ID. +* Social Media Icons Widget: Added Google+ icon. +* Social Media Icons Widget: New filter to allow you to add your own social media icons and links. +* Subscriptions: Better errors to your visitors if their subscription sign-up fails. +* Subscriptions: Removed "widget" class from Subs shortcode form. + + +Bug fixes: + +* Carousel: Fixed browser back/forward button behavior. +* Contact Form: Allow the email field to be set to empty when building form in post editor. +* Facebook Likebox Widget: Fixed an issue where some languages were not translating. +* Facebook Likebox Widget: Return a language when none found. +* General: Fixed some minor styling issues in the Jetpack admin areas. +* General: Add missing parameter to the_title filter call. +* General: Prevent scrolling of body when the Jetpack admin modals are opened. +* General: Update doc to reflect that Open Graph filter jetpack_enable_opengraph has been deprecated in favor of jetpack_enable_open_graph. +* Infinite Scroll: Fixed an error that sometimes occurred that would stop posts from loading. +* JSON API: Fixed some undefined notices when publishing a post with the API. +* Open Graph: Fixed bug where facebook description content was sometimes being polluted by a filter. +* Sharing: Use full SSL Pinterest url instead of protocol relative. +* Sharing: Fixed plus signs appearing in tweets shared from iOS. +* Shortcodes: Prefer HTTPS for video embeds to avoid mixed content warnings. +* Subscriptions Widget: Fix HTML Validation error. +* Theme Tools: Check oEmbeds for the presence of a video before adding the responsive videos filter. +* Tiled Galleries: Add image alt attribute if there is a title set. This was breaking some screen reader functionality. + += 3.7.2 = +Release date: September 29th, 2015 +Release Post: http://wp.me/p1moTy-1LB + +* Bug Fix: REST API: Fixed an error when saving drafts and publishing posts + += 3.7.1 = +Release date: September 28th, 2015 +Release Post: http://wp.me/p1moTy-1LB + +* Enhancement: General: Added inline documentation for various filters and functions +* Enhancement: General: Added custom capabilities for module management on multi-site installs +* Enhancement: General: Cleaned up old changelog entries from readme +* Enhancement: General: Cleaned up unused i18n textdomains +* Enhancement: General: Updated the new settings page to look better in various translations +* Enhancement: REST API: Added new endpoints to manage users +* Enhancement: Sharing: Updated the Google logo +* Bug Fix: Carousel: Page scroll no longer disappears after closing the carousel +* Bug Fix: Contact Form: Fields are sent and displayed in the correct order +* Bug Fix: Contact Form: No longer showing a notice on AJAX actions in feedback lists +* Bug Fix: Contact Form: Made using more than two notification emails possible +* Bug Fix: Contact Form: Mitigate a potential stored XSS vulnerability. Thanks to Marc-Alexandre Montpas (Sucuri) +* Bug Fix: General: Mitigate a potential information disclosure. Thanks to Jaime Delgado Horna +* Bug Fix: General: Fixed a locale error in the notifications popout +* Bug Fix: General: Fixed a possible fatal error in the client area +* Bug Fix: General: Fixed compatibility issues with certain use cases +* Bug Fix: General: Disabled connection warnings for multisites with domain mapping +* Bug Fix: General: Updated translations for correct link display in admin notices +* Bug Fix: REST API: Fixed a fatal error in one of the endpoints +* Bug Fix: Sharing: Fixed OpenGraph tags for Instagram embeds +* Bug Fix: Sharing: Fixed compatibility issues with bbPress +* Bug Fix: Widget Visibility: Fixed a fatal error in case of a missing tag + += 3.7.0 = +Release date: September 9th, 2015 +Release Post: http://wp.me/p1moTy-1JB + +Feature Enhancements: + +* New admin page interface to easily configure Jetpack +* Added staging site support for testing a connected Jetpack site + +Additional changes: + +* Enhancement: CLI: Added a possibility to change all options with confirmation for some of them +* Enhancement: Gallery: Added filters to allow new gallery types to be declared +* Enhancement: General: Added inline documentation for actions, filters, etc. +* Enhancement: General: Changed class variable declarations keyword from var to public +* Enhancement: General: Made the Settings page module toggle buttons more accessible +* Enhancement: General: The admin bar now loads new notifications popout +* Enhancement: General: Renamed some modules to avoid redundant prefixes +* Enhancement: General: Switched to the WordPress Core's spinner image +* Enhancement: General: Updated the bot list +* Enhancement: Manage: Added the ability to activate a network-wide plugin on a single site from WordPress.com +* Enhancement: Photon: Added a way to check image URLs against custom domains +* Enhancement: Photon: Added prompts on the media upload page telling the user about Photon +* Enhancement: Publicize: Added width and height values to OpenGraph tags for default images +* Enhancement: Related Posts: Added a filter to allow disabling nofollow +* Enhancement: REST API: Added new API endpoints to extend API functionality +* Enhancement: REST API: Added new fields to existing API endpoints +* Enhancement: Sharing: Added a possibility to opt-out of sharing for a single post +* Enhancement: Sharing: Added bbPress support +* Enhancement: Sharing: Added more configuration to the Likes modal +* Enhancement: Sharing: Made the reddit button open a new tab +* Enhancement: Sharing: Removed unused files +* Enhancement: Shortcodes: Added auto embed option inside comments +* Enhancement: Shortcodes: Added autohide parameter to the YouTube shortcode +* Enhancement: Subscriptions: added an action that triggers at the end of the subscription process +* Enhancement: VideoPress: Videos are now embedded using a new player +* Enhancement: Widget Visibility: Added parent page logic +* Enhancement: Widget Visibility: Added support for split terms +* Enhancement: Widgets: Added actions to the Social Media widget +* Enhancement: Widgets: Switched the Display Posts widget to the new API version +* Bug Fix: General: Fixed scrolling to top after modal window closing +* Bug Fix: Infinite Scroll: Added a check for cases when output buffering is disabled +* Bug Fix: Infinite Scroll: Added translation to the copyright message +* Bug Fix: Manage: Fixed automatic update synchronization on WordPress multisite network admin +* Bug Fix: Manage: Redirects back to WordPress.com are allowed from the customizer view +* Bug Fix: Media: Fixed duplicate images bug in the Media Extractor +* Bug Fix: Publicize: Made it possible to remove previously set message +* Bug Fix: Sharing: Added a thumbnail image to OpenGraph tags on pages with DailyMotion embeds +* Bug Fix: Sharing: Fixed Twitter Cards tags escaping +* Bug Fix: Sharing: Made OpenGraph tags for title and description use proper punctuation +* Bug Fix: Sharing: Made sure Likes can be disabled on the front page +* Bug Fix: Shortcodes: Fixed Facebook embeds by placing the script in the footer +* Bug Fix: Shortcodes: Fixed PollDaddy shortcode issues over SSL connections +* Bug Fix: Shortcodes: Made responsive video wrappers only wrap video embeds +* Bug Fix: Shortcodes: Made SoundCloud accept percents for dimensions +* Bug Fix: Social Links: Fixed a possible conflict with another class +* Bug Fix: Stats: Made sure the Stats URL is always escaped properly diff --git a/style.css b/style.css index 01a33ec..2700543 100644 --- a/style.css +++ b/style.css @@ -69,7 +69,7 @@ float: left; padding-right: 15px; padding-left: 15px; - width: 100%; + width: 100%; } @media only screen and (min-width: 768px) { @@ -142,6 +142,14 @@ figcaption { font-style: italic; } +/****************** + * 2.1.3 Special Containers + */ + +#header-row { + margin-bottom: 15px; +} + /*************************************** * 2.2 Text */ @@ -150,7 +158,7 @@ figcaption { * 2.2.1 Headings */ -h1, h2, h3, h3 a, h4, h5 { +h1, h2, h3, h4, h5, h6 { margin: 0; font-family: 'Montserrat', sans-serif; color: var(--dark); @@ -159,7 +167,7 @@ h1, h2, h3, h3 a, h4, h5 { #website-title { margin-left: 25px; text-align: center; - font-size: 8em; + font-size: 3.5em; font-weight: bold; text-shadow: -1px -1px 0 white, 1px -1px 0 white, @@ -350,15 +358,100 @@ a:hover { text-decoration: none; } +li a.hyperlink-button { + width: 100%; +} +.index-item { + border-bottom: 2px solid var(--dark); + overflow: hidden; + background-color: var(--light); + height: 250px; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + position: relative; + display: flex; + flex-direction: column; + margin-top: 7.5px; + margin-bottom: 7.5px; +} + +.index-item header { + background-color: var(--light); + opacity: 0.75; + margin-top: auto; + text-align: center; + padding: 15px; + max-height: 40%; +} + +.index:hover .index-item { + filter: sepia(1); +} +.index:hover .index-item:hover { + opacity: 1; + filter: none; +} + +/*************************************** + * 2.4 Images + */ + +#frontpage-img-wrapper { + border-radius: 50%; + margin: auto; + overflow: hidden; + height: 150px; + width: 150px; + border: 2px solid #003D52; +} + +#frontpage-img { + max-width: 150%; + height: 150%; +} + +.entry-content img:not(.latex) { + border: 2px solid #444; +} + +.latex { + vertical-align: middle; +} + +.aligncenter { + text-align: center; + margin: 1em auto 1em auto; + display: block; +} + +.entry-content img { + max-width: 100%; + height: auto; +} + +.post-header-image { + height:100vh; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + position: relative; + text-align:center; +} + +.sampler { + width: 100%; + height: 60vh; +} /* - * UNFINISHED - */ + * AUTHOR STUFF - CURRENTLY UNNECESSARY + * .author a { border-radius: 0 35px 35px 0; @@ -386,96 +479,6 @@ a:hover { color: #999; } -.index article { - border-bottom: 2px solid var(--dark); - overflow: hidden; - background-color: var(--light); - height: 250px; - background-size: cover; - background-repeat: no-repeat; - background-position: center; - position: relative; - display: flex; - flex-direction: column; - margin-top: 7.5px; - margin-bottom: 7.5px; -} - -.index article header { - background-color: var(--light); - opacity: 0.75; - margin-top: auto; - text-align: center; - padding: 15px; - max-height: 40%; -} - - -.index:hover article { - filter: sepia(1); -} -.index:hover article:hover { - opacity: 1; - filter: none; -} - -/* - * 4. Images - */ - -#frontpage-img-wrapper { - border-radius: 50%; - margin: auto; - overflow: hidden; - height: 150px; - width: 150px; - border: 2px solid #003D52; -} - -#frontpage-img { - max-width: 150%; - height: 150%; -} - -.post-thumbnail { - float: left; - overflow: hidden; - width: 100%; - height: 15em; - cursor: pointer; - background-color: #fff; - background-size: cover; - background-repeat: no-repeat; - background-position: center; -} - -.post-thumbnail .post-thumbnail-label { - position: relative; - text-align: center; - opacity: 0; - font-size: 2em; - color: #003D52; - height: 100%; - line-height: 240px; -} -.post-thumbnail:hover .post-thumbnail-label { - animation: both fadeinanddarken 0.3s; -} - -.single-img .title { - position: relative; - top: 50%; - left: 30%; -} - -.entry-content img:not(.latex) { - border: 2px solid #444; -} - -.latex { - vertical-align: middle; -} - .author img { padding: 5px; border-radius: 50%; @@ -483,71 +486,10 @@ a:hover { background-color: #95b2bf; } -.post-header-image { - height:100vh; - background-size: cover; - background-repeat: no-repeat; - background-position: center; - position: relative; - text-align:center; -} - -.aligncenter { - text-align: center; - margin: 1em auto 1em auto; - display: block; -} +*/ -.blog-post .entry-content img { - height: auto; - max-width: 100%; -} - -.sampler { - width: 100%; - height: 60vh; -} - -/* - * 5. Article List View - */ - -article.entry-header { - margin-bottom: -100px; -} - -.post-details { - position: relative; - overflow: hidden; - width: auto; - margin-top: 10px; - margin-bottom: 10px; - text-align: justify; - padding: 20px; -} - -.post-details header, .post-details footer, .post-details .entry-content { - width: 100%; - overflow: hidden; - line-height: 2.3em; -} - -.post-details footer { - height: 4.5em; - position: absolute; - bottom: 0; - left: 0; - padding: 0 0 0 10px; -} - -.author { - opacity: 0.7; -} -.author:hover { - opacity: 1; -} .post-header-image .post-header-title { position: absolute; @@ -983,8 +925,8 @@ float: right; */ @media only screen and (min-width: 768px) { - h1 { - text-align: left; + #website-title { + font-size: 4.5em; } .blog-post .entry-content { width: 80%; @@ -993,8 +935,11 @@ float: right; } @media only screen and (min-width: 1024px) { - h5 { - text-align: left; + #website-title { + font-size: 8em; + } + .frontpage-section-title { + text-align: left; } #frontpage-img-wrapper { display: none; diff --git a/taxonomy-company.php b/taxonomy-company.php index 77a3753..fadf807 100644 --- a/taxonomy-company.php +++ b/taxonomy-company.php @@ -1,143 +1,143 @@ - - $startDate)); - } - - $company = get_queried_object(); - $args= array( - 'post_type' => array( 'job' ), - 'tax_query' => array( - array( - 'taxonomy' => 'company', - 'field' => 'slug', - 'terms' => $company->name, - ), - ), - 'posts_per_page' => -1 - ); - - $loop = new WP_Query( $args ) -?> - - -
-
- - -
-
-
-

Children

-
    - false, 'taxonomy' => 'company', 'term_args' => array('child_of' => get_queried_object()->term_id))); - foreach ( (array) $children as $child ) { - $imgURL = wp_get_attachment_image_src($child->image_id, 'detail')[0]; - $colour = get_term_meta($child->term_id, 'color', true); - $colour = ($colour != "") ? $colour : "var(--light)"; - echo "taxonomy ))."\">
  • "; - } - ?> -
-
-
- have_posts() ) : - echo "
"; - echo "

".ucwords($currSec)."s slug."\">View all ".$loop->post_count."

"; - echo "
"; - while ( $loop->have_posts() ) : $loop->the_post(); - get_template_part( 'template-parts/content', get_post_format() ); - endwhile; - echo "
"; - echo "
"; - endif; - } - ?> -
-
- - - + + $startDate)); + } + + $company = get_queried_object(); + $args= array( + 'post_type' => array( 'job' ), + 'tax_query' => array( + array( + 'taxonomy' => 'company', + 'field' => 'slug', + 'terms' => $company->name, + ), + ), + 'posts_per_page' => -1 + ); + + $loop = new WP_Query( $args ) +?> + + +
+
+ + +
+
+
+

Children

+
    + false, 'taxonomy' => 'company', 'term_args' => array('child_of' => get_queried_object()->term_id))); + foreach ( (array) $children as $child ) { + $imgURL = wp_get_attachment_image_src($child->image_id, 'detail')[0]; + $colour = get_term_meta($child->term_id, 'color', true); + $colour = ($colour != "") ? $colour : "var(--light)"; + echo "taxonomy ))."\">
  • "; + } + ?> +
+
+
+ have_posts() ) : + echo "
"; + echo "

".ucwords($currSec)."s slug."\">View all ".$loop->post_count."

"; + echo "
"; + while ( $loop->have_posts() ) : $loop->the_post(); + get_template_part( 'template-parts/content', get_post_format() ); + endwhile; + echo "
"; + echo "
"; + endif; + } + ?> +
+
+ + + diff --git a/template-parts/.content-single.php.swp b/template-parts/.content-single.php.swp index cac31ada9b4a9dce7c7eafe45e99d98b5443b8cb..78dbbcc7d9655fbe602ec25ea4fd4297fcaca94c 100644 GIT binary patch delta 49 qcmZoj=t$VGRzZcAi-F-gh`0tKR)dK7AfgRK6oLpd-pwZ!%=rN#pb9 -
style="background-image: url('');"> +