summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo Chatzimichos <tampakrap@gentoo.org>2013-08-01 08:53:46 +0200
committerTheo Chatzimichos <tampakrap@gentoo.org>2013-08-01 08:53:46 +0200
commitc65f25a29edb6d47fa7d99a69c274f906b61adea (patch)
tree3f85de9f4159f72bb555310a6e4e5da75276a7ff /plugins/jetpack
parentbump kde-graffiti (diff)
downloadblogs-gentoo-c65f25a29edb6d47fa7d99a69c274f906b61adea.tar.gz
blogs-gentoo-c65f25a29edb6d47fa7d99a69c274f906b61adea.tar.bz2
blogs-gentoo-c65f25a29edb6d47fa7d99a69c274f906b61adea.zip
Update jetpack, akismet and wordpress-importer
Diffstat (limited to 'plugins/jetpack')
-rw-r--r--plugins/jetpack/_inc/gallery-settings.js15
-rw-r--r--plugins/jetpack/_inc/images/a8c.pngbin2058 -> 845 bytes
-rw-r--r--plugins/jetpack/_inc/images/alertbox-closeicon-2x.pngbin515 -> 245 bytes
-rw-r--r--plugins/jetpack/_inc/images/alertbox-closeicon.pngbin437 -> 240 bytes
-rw-r--r--plugins/jetpack/_inc/images/alertbox-clouds-2x.pngbin2247 -> 1308 bytes
-rw-r--r--plugins/jetpack/_inc/images/alertbox-clouds.pngbin1088 -> 640 bytes
-rw-r--r--plugins/jetpack/_inc/images/arrow-2x.pngbin460 -> 267 bytes
-rw-r--r--plugins/jetpack/_inc/images/arrow-pointer-blue-2x.pngbin3022 -> 2052 bytes
-rw-r--r--plugins/jetpack/_inc/images/arrow.pngbin296 -> 173 bytes
-rw-r--r--plugins/jetpack/_inc/images/arrows-2x.pngbin1371 -> 978 bytes
-rw-r--r--plugins/jetpack/_inc/images/arrows-dark-2x.pngbin1416 -> 958 bytes
-rw-r--r--plugins/jetpack/_inc/images/arrows-dark-vs-2x.pngbin1287 -> 1093 bytes
-rw-r--r--plugins/jetpack/_inc/images/arrows-vs-2x.pngbin1213 -> 1079 bytes
-rw-r--r--plugins/jetpack/_inc/images/atdbuttontr-2x.pngbin1840 -> 1598 bytes
-rw-r--r--plugins/jetpack/_inc/images/automattic-2x.pngbin5902 -> 3851 bytes
-rw-r--r--plugins/jetpack/_inc/images/automattic.pngbin3056 -> 1904 bytes
-rw-r--r--plugins/jetpack/_inc/images/bubble_bg-2x.pngbin570 -> 532 bytes
-rw-r--r--plugins/jetpack/_inc/images/comment-grey-bubble-2x.pngbin256 -> 175 bytes
-rw-r--r--plugins/jetpack/_inc/images/delete-2x.pngbin4009 -> 3687 bytes
-rw-r--r--plugins/jetpack/_inc/images/footer-clouds-2x.pngbin63998 -> 57101 bytes
-rw-r--r--plugins/jetpack/_inc/images/footer-clouds.pngbin23583 -> 20077 bytes
-rw-r--r--plugins/jetpack/_inc/images/generic-2x.pngbin2166 -> 1826 bytes
-rw-r--r--plugins/jetpack/_inc/images/header-clouds-2x.pngbin78134 -> 50373 bytes
-rw-r--r--plugins/jetpack/_inc/images/header-clouds-small-2x.pngbin29032 -> 18157 bytes
-rw-r--r--plugins/jetpack/_inc/images/header-clouds-small.pngbin12781 -> 7969 bytes
-rw-r--r--plugins/jetpack/_inc/images/header-clouds.pngbin30454 -> 18565 bytes
-rw-r--r--plugins/jetpack/_inc/images/icon-comingsoon-2x.pngbin3096 -> 1960 bytes
-rw-r--r--plugins/jetpack/_inc/images/icon-comingsoon.pngbin1482 -> 896 bytes
-rw-r--r--plugins/jetpack/_inc/images/icon-pointer-flag-2x.pngbin2427 -> 1747 bytes
-rw-r--r--plugins/jetpack/_inc/images/image-2x.pngbin5414 -> 2671 bytes
-rw-r--r--plugins/jetpack/_inc/images/imgedit-icons-2x.pngbin17070 -> 15590 bytes
-rw-r--r--plugins/jetpack/_inc/images/jetpack-closebox-icon.pngbin388 -> 189 bytes
-rw-r--r--plugins/jetpack/_inc/images/list-2x.pngbin2052 -> 2000 bytes
-rw-r--r--plugins/jetpack/_inc/images/logo-2x.pngbin52802 -> 50369 bytes
-rw-r--r--plugins/jetpack/_inc/images/logo-small-2x.pngbin28124 -> 27389 bytes
-rw-r--r--plugins/jetpack/_inc/images/logo-small.pngbin11205 -> 10611 bytes
-rw-r--r--plugins/jetpack/_inc/images/logo.pngbin22543 -> 21731 bytes
-rw-r--r--plugins/jetpack/_inc/images/media-button-2x.pngbin1206 -> 875 bytes
-rw-r--r--plugins/jetpack/_inc/images/menuicon-sprite-2x.pngbin4456 -> 3688 bytes
-rw-r--r--plugins/jetpack/_inc/images/menuicon-sprite.pngbin1652 -> 1351 bytes
-rw-r--r--plugins/jetpack/_inc/images/module-clouds-2x.pngbin5942 -> 5375 bytes
-rw-r--r--plugins/jetpack/_inc/images/module-clouds.pngbin2646 -> 2378 bytes
-rw-r--r--plugins/jetpack/_inc/images/module-icons-sprite-2x.pngbin72735 -> 59781 bytes
-rw-r--r--plugins/jetpack/_inc/images/module-icons-sprite.pngbin31542 -> 28049 bytes
-rw-r--r--plugins/jetpack/_inc/images/press-this-2x.pngbin887 -> 821 bytes
-rw-r--r--plugins/jetpack/_inc/images/publicize.pngbin113219 -> 81768 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/blue-large.pngbin1797 -> 1776 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/blue-medium.pngbin1213 -> 1195 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/blue-small.pngbin618 -> 597 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/green-large.pngbin1665 -> 1644 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/green-medium.pngbin1057 -> 1036 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/green-small.pngbin549 -> 528 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/orange-large.pngbin2570 -> 2545 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/orange-medium.pngbin1718 -> 1697 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/orange-small.pngbin712 -> 672 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/pink-large.pngbin3639 -> 3617 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/pink-medium.pngbin1574 -> 1553 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/purple-large.pngbin3778 -> 3755 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/purple-medium.pngbin1723 -> 1702 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/purple-small.pngbin707 -> 651 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/red-large.pngbin3618 -> 3595 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/red-medium.pngbin1579 -> 1558 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/red-small.pngbin675 -> 609 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/silver-large.pngbin2141 -> 2120 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/silver-medium.pngbin874 -> 853 bytes
-rw-r--r--plugins/jetpack/_inc/images/rss/silver-small.pngbin355 -> 336 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/beautifulmath.pngbin45978 -> 41588 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/carousel.pngbin361672 -> 345257 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/comments.pngbin36696 -> 31650 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/contactform.pngbin40668 -> 33236 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/custom-css.pngbin43048 -> 25789 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/hovercards.pngbin105102 -> 103110 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/likes.pngbin48953 -> 45802 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/mobile-push-notifications.jpgbin29830 -> 29242 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/notes.pngbin27450 -> 24032 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/post-by-email.pngbin28349 -> 25973 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/publicize.pngbin113219 -> 81768 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/sharing.pngbin36342 -> 35544 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/shortcodes.pngbin46029 -> 35980 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/shortlinks.pngbin54587 -> 52873 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/spelling.pngbin59981 -> 56568 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/stats.pngbin80732 -> 74882 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/subscriptions.pngbin52112 -> 43275 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/tiled-gallery.pngbin192182 -> 186121 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/vaultpress.pngbin45517 -> 39774 bytes
-rw-r--r--plugins/jetpack/_inc/images/screenshots/widgets.pngbin107072 -> 106129 bytes
-rw-r--r--plugins/jetpack/_inc/images/stars-2x.pngbin1388 -> 1022 bytes
-rw-r--r--plugins/jetpack/_inc/images/status-light-2x.pngbin2309 -> 1771 bytes
-rw-r--r--plugins/jetpack/_inc/images/status-light.pngbin1006 -> 703 bytes
-rw-r--r--plugins/jetpack/_inc/images/tb-close-2x.pngbin337 -> 197 bytes
-rw-r--r--plugins/jetpack/_inc/jetpack-retina.css191
-rw-r--r--plugins/jetpack/_inc/jetpack-rtl.css238
-rw-r--r--plugins/jetpack/_inc/jetpack.css1728
-rw-r--r--plugins/jetpack/_inc/jetpack.js1
-rw-r--r--plugins/jetpack/_inc/jquery.inview.js8
-rw-r--r--plugins/jetpack/_inc/jquery.jetpack-resize.js17
-rw-r--r--plugins/jetpack/_inc/jquery.spin.js180
-rw-r--r--plugins/jetpack/_inc/postmessage.js6
-rw-r--r--plugins/jetpack/_inc/spin.js642
-rw-r--r--plugins/jetpack/class.jetpack-ixr-client.php2
-rw-r--r--plugins/jetpack/class.jetpack-post-images.php32
-rw-r--r--plugins/jetpack/class.jetpack-signature.php4
-rw-r--r--plugins/jetpack/class.jetpack-user-agent.php158
-rw-r--r--plugins/jetpack/class.jetpack-xmlrpc-server.php6
-rw-r--r--plugins/jetpack/class.json-api-endpoints.php466
-rw-r--r--plugins/jetpack/class.json-api.php81
-rw-r--r--plugins/jetpack/class.photon.php6
-rw-r--r--plugins/jetpack/functions.gallery.php9
-rw-r--r--plugins/jetpack/functions.opengraph.php24
-rw-r--r--plugins/jetpack/functions.photon.php4
-rw-r--r--plugins/jetpack/jetpack.php4488
-rw-r--r--plugins/jetpack/languages/jetpack-ar.mobin14004 -> 132582 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-az.mobin2886 -> 3077 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-bs_BA.mobin76528 -> 76232 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-ca.mobin76602 -> 79877 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-cs_CZ.mobin8242 -> 8967 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-da_DK.mobin44830 -> 44531 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-de_DE.mobin117625 -> 123046 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-el.mobin8337 -> 12312 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-es_ES.mobin49121 -> 73672 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-fa_IR.mobin47862 -> 58196 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-fi.mobin27526 -> 28822 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-fr_FR.mobin113684 -> 127742 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-gl_ES.mobin33955 -> 34697 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-he_IL.mobin75590 -> 75006 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-hr.mobin35895 -> 36776 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-hu_HU.mobin77710 -> 99073 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-id_ID.mobin52347 -> 51973 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-it_IT.mobin50000 -> 62055 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-ja.mobin116549 -> 131786 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-ko_KR.mobin110462 -> 121971 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-lt_LT.mobin12440 -> 14165 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-mk_MK.mobin23594 -> 24002 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-my_MM.mobin11071 -> 12429 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-nb_NO.mobin88203 -> 96717 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-nl_NL.mobin38043 -> 38431 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-nn_NO.mobin14701 -> 16249 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-pl_PL.mobin11997 -> 19309 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-pt_BR.mobin107473 -> 110039 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-pt_PT.mobin46165 -> 46473 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-ro_RO.mobin10652 -> 11212 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-ru_RU.mobin49300 -> 49671 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-sa_IN.mobin1006 -> 1006 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-sk_SK.mobin10517 -> 11359 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-sq.mobin112583 -> 111067 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-sr_RS.mobin44079 -> 54018 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-sv_SE.mobin24534 -> 33308 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-th.mobin18421 -> 20113 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-tr_TR.mobin35311 -> 36876 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-zh_CN.mobin7637 -> 8477 bytes
-rw-r--r--plugins/jetpack/languages/jetpack-zh_TW.mobin93742 -> 91924 bytes
-rw-r--r--plugins/jetpack/locales.php10
-rw-r--r--plugins/jetpack/modules/after-the-deadline.php35
-rw-r--r--plugins/jetpack/modules/after-the-deadline/atd-autoproofread.js6
-rw-r--r--plugins/jetpack/modules/after-the-deadline/atd-nonvis-editor-plugin.js20
-rw-r--r--plugins/jetpack/modules/after-the-deadline/atd.core.js58
-rw-r--r--plugins/jetpack/modules/after-the-deadline/atd.css32
-rw-r--r--plugins/jetpack/modules/after-the-deadline/config-options.php26
-rw-r--r--plugins/jetpack/modules/after-the-deadline/config-unignore.php10
-rw-r--r--plugins/jetpack/modules/after-the-deadline/install_atd_l10n.js4
-rw-r--r--plugins/jetpack/modules/after-the-deadline/jquery.atd.js44
-rw-r--r--plugins/jetpack/modules/after-the-deadline/proxy.php8
-rw-r--r--plugins/jetpack/modules/after-the-deadline/tinymce/editor_plugin.js126
-rw-r--r--plugins/jetpack/modules/carousel.php1
-rw-r--r--plugins/jetpack/modules/carousel/jetpack-carousel.css34
-rw-r--r--plugins/jetpack/modules/carousel/jetpack-carousel.js209
-rw-r--r--plugins/jetpack/modules/carousel/jetpack-carousel.php69
-rw-r--r--plugins/jetpack/modules/carousel/rtl/jetpack-carousel-rtl.css36
-rw-r--r--plugins/jetpack/modules/comments.php1
-rw-r--r--plugins/jetpack/modules/comments/admin.php2
-rw-r--r--plugins/jetpack/modules/comments/base.php14
-rw-r--r--plugins/jetpack/modules/comments/comments.php19
-rw-r--r--plugins/jetpack/modules/contact-form.php3
-rw-r--r--plugins/jetpack/modules/contact-form/admin.php47
-rw-r--r--plugins/jetpack/modules/contact-form/css/grunion.css4
-rw-r--r--plugins/jetpack/modules/contact-form/grunion-contact-form.php414
-rw-r--r--plugins/jetpack/modules/contact-form/grunion-form-view.php22
-rw-r--r--plugins/jetpack/modules/contact-form/js/grunion.js34
-rw-r--r--plugins/jetpack/modules/custom-css.php1
-rw-r--r--plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php7
-rw-r--r--plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php9
-rw-r--r--plugins/jetpack/modules/custom-css/csstidy/class.csstidy_print.php4
-rw-r--r--plugins/jetpack/modules/custom-css/csstidy/data-wp.inc.php8
-rw-r--r--plugins/jetpack/modules/custom-css/csstidy/data.inc.php4
-rw-r--r--plugins/jetpack/modules/custom-css/csstidy/lang.inc.php8
-rw-r--r--plugins/jetpack/modules/custom-css/custom-css.php425
-rw-r--r--plugins/jetpack/modules/custom-css/custom-css/js/ace/ace.js1
-rw-r--r--plugins/jetpack/modules/custom-css/custom-css/js/ace/worker-css.js7887
-rw-r--r--plugins/jetpack/modules/custom-css/custom-css/js/safecss-ace.js53
-rw-r--r--plugins/jetpack/modules/custom-css/custom-css/preprocessors.php2
-rw-r--r--plugins/jetpack/modules/enhanced-distribution.php1
-rw-r--r--plugins/jetpack/modules/featured-content/featured-content.php6
-rw-r--r--plugins/jetpack/modules/gravatar-hovercards.php11
-rw-r--r--plugins/jetpack/modules/holiday-snow.php1
-rw-r--r--plugins/jetpack/modules/infinite-scroll.php1
-rw-r--r--plugins/jetpack/modules/infinite-scroll/infinity.css5
-rw-r--r--plugins/jetpack/modules/infinite-scroll/infinity.js9
-rw-r--r--plugins/jetpack/modules/infinite-scroll/infinity.php134
-rw-r--r--plugins/jetpack/modules/json-api.php1
-rw-r--r--plugins/jetpack/modules/latex.php1
-rw-r--r--plugins/jetpack/modules/likes.php214
-rw-r--r--plugins/jetpack/modules/likes/style.css19
-rw-r--r--plugins/jetpack/modules/minileven.php1
-rw-r--r--plugins/jetpack/modules/minileven/minileven.php17
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/content-gallery.php4
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/content.php13
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/footer.php2
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/functions.php56
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/header.php20
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/image.php2
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/inc/custom-header.php36
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/inc/template-tags.php5
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/inc/tweaks.php22
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/index.php2
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/js/small-menu.js64
-rw-r--r--plugins/jetpack/modules/minileven/theme/pub/minileven/style.css624
-rw-r--r--plugins/jetpack/modules/mobile-push.php3
-rw-r--r--plugins/jetpack/modules/module-extras.php2
-rw-r--r--plugins/jetpack/modules/module-info.php48
-rw-r--r--plugins/jetpack/modules/notes.php82
-rw-r--r--plugins/jetpack/modules/photon.php1
-rw-r--r--plugins/jetpack/modules/post-by-email.php5
-rw-r--r--plugins/jetpack/modules/post-by-email/post-by-email.js2
-rw-r--r--plugins/jetpack/modules/publicize.php1
-rw-r--r--plugins/jetpack/modules/publicize/assets/publicize.css5
-rw-r--r--plugins/jetpack/modules/publicize/assets/publicize.js2
-rw-r--r--plugins/jetpack/modules/publicize/assets/rtl/publicize-rtl.css7
-rw-r--r--plugins/jetpack/modules/publicize/publicize-jetpack.php93
-rw-r--r--plugins/jetpack/modules/publicize/publicize.php45
-rw-r--r--plugins/jetpack/modules/publicize/ui.php39
-rw-r--r--plugins/jetpack/modules/sharedaddy.php3
-rw-r--r--plugins/jetpack/modules/sharedaddy/admin-sharing.css46
-rw-r--r--plugins/jetpack/modules/sharedaddy/admin-sharing.js108
-rw-r--r--plugins/jetpack/modules/sharedaddy/images/facebook.pngbin838 -> 568 bytes
-rw-r--r--plugins/jetpack/modules/sharedaddy/images/facebook@2x.pngbin1533 -> 1036 bytes
-rw-r--r--plugins/jetpack/modules/sharedaddy/images/googleplus1.pngbin574 -> 722 bytes
-rw-r--r--plugins/jetpack/modules/sharedaddy/images/googleplus1@2x.pngbin1815 -> 1333 bytes
-rw-r--r--plugins/jetpack/modules/sharedaddy/images/icon-facebook-2x.pngbin671 -> 1036 bytes
-rw-r--r--plugins/jetpack/modules/sharedaddy/images/icon-facebook.pngbin887 -> 568 bytes
-rw-r--r--plugins/jetpack/modules/sharedaddy/recaptchalib.php14
-rw-r--r--plugins/jetpack/modules/sharedaddy/sharedaddy.php6
-rw-r--r--plugins/jetpack/modules/sharedaddy/sharing-service.php42
-rw-r--r--plugins/jetpack/modules/sharedaddy/sharing-sources.php91
-rw-r--r--plugins/jetpack/modules/sharedaddy/sharing.css71
-rw-r--r--plugins/jetpack/modules/sharedaddy/sharing.js11
-rw-r--r--plugins/jetpack/modules/sharedaddy/sharing.php1
-rw-r--r--plugins/jetpack/modules/shortcodes.php35
-rw-r--r--plugins/jetpack/modules/shortcodes/archives.php2
-rw-r--r--plugins/jetpack/modules/shortcodes/audio.php31
-rw-r--r--plugins/jetpack/modules/shortcodes/blip.php6
-rw-r--r--plugins/jetpack/modules/shortcodes/css/rtl/slideshow-shortcode-rtl.css4
-rw-r--r--plugins/jetpack/modules/shortcodes/css/slideshow-shortcode.css2
-rw-r--r--plugins/jetpack/modules/shortcodes/dailymotion.php32
-rw-r--r--plugins/jetpack/modules/shortcodes/diggthis.php14
-rw-r--r--plugins/jetpack/modules/shortcodes/flickr.php10
-rw-r--r--plugins/jetpack/modules/shortcodes/googlemaps.php4
-rw-r--r--plugins/jetpack/modules/shortcodes/googlevideo.php4
-rw-r--r--plugins/jetpack/modules/shortcodes/js/audio-shortcode.js12
-rw-r--r--plugins/jetpack/modules/shortcodes/js/jquery.cycle.js40
-rw-r--r--plugins/jetpack/modules/shortcodes/polldaddy.php168
-rw-r--r--plugins/jetpack/modules/shortcodes/slideshare.php4
-rw-r--r--plugins/jetpack/modules/shortcodes/slideshow.php2
-rw-r--r--plugins/jetpack/modules/shortcodes/ted.php4
-rw-r--r--plugins/jetpack/modules/shortcodes/videopress.php18
-rw-r--r--plugins/jetpack/modules/shortcodes/vimeo.php27
-rw-r--r--plugins/jetpack/modules/shortcodes/youtube.php43
-rw-r--r--plugins/jetpack/modules/shortlinks.php1
-rw-r--r--plugins/jetpack/modules/stats.php73
-rw-r--r--plugins/jetpack/modules/subscriptions.php53
-rw-r--r--plugins/jetpack/modules/tiled-gallery.php1
-rw-r--r--plugins/jetpack/modules/tiled-gallery/math/class-constrained-array-rounding.php6
-rw-r--r--plugins/jetpack/modules/tiled-gallery/tiled-gallery.php34
-rw-r--r--plugins/jetpack/modules/tiled-gallery/tiled-gallery/rtl/tiled-gallery-rtl.css15
-rw-r--r--plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.css12
-rw-r--r--plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.js15
-rw-r--r--plugins/jetpack/modules/vaultpress.php5
-rw-r--r--plugins/jetpack/modules/widgets.php11
-rw-r--r--plugins/jetpack/modules/widgets/facebook-likebox.php78
-rw-r--r--plugins/jetpack/modules/widgets/gravatar-profile.css2
-rw-r--r--plugins/jetpack/modules/widgets/readmill.php2
-rw-r--r--plugins/jetpack/modules/widgets/rsslinks-widget.php2
-rw-r--r--plugins/jetpack/modules/widgets/top-posts.php16
-rw-r--r--plugins/jetpack/readme.txt210
283 files changed, 13280 insertions, 7720 deletions
diff --git a/plugins/jetpack/_inc/gallery-settings.js b/plugins/jetpack/_inc/gallery-settings.js
index 0ce38f0b..4b5316b8 100644
--- a/plugins/jetpack/_inc/gallery-settings.js
+++ b/plugins/jetpack/_inc/gallery-settings.js
@@ -7,12 +7,25 @@
// Wrap the render() function to append controls.
media.view.Settings.Gallery = media.view.Settings.Gallery.extend({
render: function() {
+ var $el = this.$el;
+
media.view.Settings.prototype.render.apply( this, arguments );
// Append the type template and update the settings.
- this.$el.append( media.template( 'jetpack-gallery-settings' ) );
+ $el.append( media.template( 'jetpack-gallery-settings' ) );
media.gallery.defaults.type = 'default'; // lil hack that lets media know there's a type attribute.
this.update.apply( this, ['type'] );
+
+ // Hide the Columns setting for all types except Default
+ $el.find( 'select[name=type]' ).on( 'change', function () {
+ var columnSetting = $el.find( 'select[name=columns]' ).closest( 'label.setting' );
+
+ if ( 'default' == $( this ).val() )
+ columnSetting.show();
+ else
+ columnSetting.hide();
+ } ).change();
+
return this;
}
});
diff --git a/plugins/jetpack/_inc/images/a8c.png b/plugins/jetpack/_inc/images/a8c.png
index b6c84df9..d31d6e3b 100644
--- a/plugins/jetpack/_inc/images/a8c.png
+++ b/plugins/jetpack/_inc/images/a8c.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/alertbox-closeicon-2x.png b/plugins/jetpack/_inc/images/alertbox-closeicon-2x.png
index 5c64a0e1..e78f4482 100644
--- a/plugins/jetpack/_inc/images/alertbox-closeicon-2x.png
+++ b/plugins/jetpack/_inc/images/alertbox-closeicon-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/alertbox-closeicon.png b/plugins/jetpack/_inc/images/alertbox-closeicon.png
index c293dafa..ad3a3264 100644
--- a/plugins/jetpack/_inc/images/alertbox-closeicon.png
+++ b/plugins/jetpack/_inc/images/alertbox-closeicon.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/alertbox-clouds-2x.png b/plugins/jetpack/_inc/images/alertbox-clouds-2x.png
index 770390f6..bfa71b2a 100644
--- a/plugins/jetpack/_inc/images/alertbox-clouds-2x.png
+++ b/plugins/jetpack/_inc/images/alertbox-clouds-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/alertbox-clouds.png b/plugins/jetpack/_inc/images/alertbox-clouds.png
index 207dd2a3..4a40a7e1 100644
--- a/plugins/jetpack/_inc/images/alertbox-clouds.png
+++ b/plugins/jetpack/_inc/images/alertbox-clouds.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/arrow-2x.png b/plugins/jetpack/_inc/images/arrow-2x.png
index 668bd220..6b83e7cd 100644
--- a/plugins/jetpack/_inc/images/arrow-2x.png
+++ b/plugins/jetpack/_inc/images/arrow-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/arrow-pointer-blue-2x.png b/plugins/jetpack/_inc/images/arrow-pointer-blue-2x.png
index 5c567fad..29c7dcf8 100644
--- a/plugins/jetpack/_inc/images/arrow-pointer-blue-2x.png
+++ b/plugins/jetpack/_inc/images/arrow-pointer-blue-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/arrow.png b/plugins/jetpack/_inc/images/arrow.png
index 995148cb..25d2f027 100644
--- a/plugins/jetpack/_inc/images/arrow.png
+++ b/plugins/jetpack/_inc/images/arrow.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/arrows-2x.png b/plugins/jetpack/_inc/images/arrows-2x.png
index 752f3e2a..5004253b 100644
--- a/plugins/jetpack/_inc/images/arrows-2x.png
+++ b/plugins/jetpack/_inc/images/arrows-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/arrows-dark-2x.png b/plugins/jetpack/_inc/images/arrows-dark-2x.png
index cc665817..9e1b44f2 100644
--- a/plugins/jetpack/_inc/images/arrows-dark-2x.png
+++ b/plugins/jetpack/_inc/images/arrows-dark-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/arrows-dark-vs-2x.png b/plugins/jetpack/_inc/images/arrows-dark-vs-2x.png
index 908daa6b..4b667c4a 100644
--- a/plugins/jetpack/_inc/images/arrows-dark-vs-2x.png
+++ b/plugins/jetpack/_inc/images/arrows-dark-vs-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/arrows-vs-2x.png b/plugins/jetpack/_inc/images/arrows-vs-2x.png
index 50af7389..1ecd8291 100644
--- a/plugins/jetpack/_inc/images/arrows-vs-2x.png
+++ b/plugins/jetpack/_inc/images/arrows-vs-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/atdbuttontr-2x.png b/plugins/jetpack/_inc/images/atdbuttontr-2x.png
index 8d3617e5..5086e088 100644
--- a/plugins/jetpack/_inc/images/atdbuttontr-2x.png
+++ b/plugins/jetpack/_inc/images/atdbuttontr-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/automattic-2x.png b/plugins/jetpack/_inc/images/automattic-2x.png
index 412bee1a..661556a1 100644
--- a/plugins/jetpack/_inc/images/automattic-2x.png
+++ b/plugins/jetpack/_inc/images/automattic-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/automattic.png b/plugins/jetpack/_inc/images/automattic.png
index dc1c3a7e..9c0c3886 100644
--- a/plugins/jetpack/_inc/images/automattic.png
+++ b/plugins/jetpack/_inc/images/automattic.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/bubble_bg-2x.png b/plugins/jetpack/_inc/images/bubble_bg-2x.png
index f5353136..8757def4 100644
--- a/plugins/jetpack/_inc/images/bubble_bg-2x.png
+++ b/plugins/jetpack/_inc/images/bubble_bg-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/comment-grey-bubble-2x.png b/plugins/jetpack/_inc/images/comment-grey-bubble-2x.png
index 72e02404..57fbeacf 100644
--- a/plugins/jetpack/_inc/images/comment-grey-bubble-2x.png
+++ b/plugins/jetpack/_inc/images/comment-grey-bubble-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/delete-2x.png b/plugins/jetpack/_inc/images/delete-2x.png
index 5c869b17..9436624a 100644
--- a/plugins/jetpack/_inc/images/delete-2x.png
+++ b/plugins/jetpack/_inc/images/delete-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/footer-clouds-2x.png b/plugins/jetpack/_inc/images/footer-clouds-2x.png
index f6b7454e..4616c0af 100644
--- a/plugins/jetpack/_inc/images/footer-clouds-2x.png
+++ b/plugins/jetpack/_inc/images/footer-clouds-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/footer-clouds.png b/plugins/jetpack/_inc/images/footer-clouds.png
index e7c8d057..d8dc03a7 100644
--- a/plugins/jetpack/_inc/images/footer-clouds.png
+++ b/plugins/jetpack/_inc/images/footer-clouds.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/generic-2x.png b/plugins/jetpack/_inc/images/generic-2x.png
index 85c6f85b..0f7b28f6 100644
--- a/plugins/jetpack/_inc/images/generic-2x.png
+++ b/plugins/jetpack/_inc/images/generic-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/header-clouds-2x.png b/plugins/jetpack/_inc/images/header-clouds-2x.png
index 0762edfe..2fdf221f 100644
--- a/plugins/jetpack/_inc/images/header-clouds-2x.png
+++ b/plugins/jetpack/_inc/images/header-clouds-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/header-clouds-small-2x.png b/plugins/jetpack/_inc/images/header-clouds-small-2x.png
index a5ab65c1..04387676 100644
--- a/plugins/jetpack/_inc/images/header-clouds-small-2x.png
+++ b/plugins/jetpack/_inc/images/header-clouds-small-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/header-clouds-small.png b/plugins/jetpack/_inc/images/header-clouds-small.png
index c1a6b273..00bbf16f 100644
--- a/plugins/jetpack/_inc/images/header-clouds-small.png
+++ b/plugins/jetpack/_inc/images/header-clouds-small.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/header-clouds.png b/plugins/jetpack/_inc/images/header-clouds.png
index a766222e..ce8fea9f 100644
--- a/plugins/jetpack/_inc/images/header-clouds.png
+++ b/plugins/jetpack/_inc/images/header-clouds.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/icon-comingsoon-2x.png b/plugins/jetpack/_inc/images/icon-comingsoon-2x.png
index baede10f..ea426d49 100644
--- a/plugins/jetpack/_inc/images/icon-comingsoon-2x.png
+++ b/plugins/jetpack/_inc/images/icon-comingsoon-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/icon-comingsoon.png b/plugins/jetpack/_inc/images/icon-comingsoon.png
index 3814c86e..ecfce9ba 100644
--- a/plugins/jetpack/_inc/images/icon-comingsoon.png
+++ b/plugins/jetpack/_inc/images/icon-comingsoon.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/icon-pointer-flag-2x.png b/plugins/jetpack/_inc/images/icon-pointer-flag-2x.png
index 057545a5..b130901b 100644
--- a/plugins/jetpack/_inc/images/icon-pointer-flag-2x.png
+++ b/plugins/jetpack/_inc/images/icon-pointer-flag-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/image-2x.png b/plugins/jetpack/_inc/images/image-2x.png
index a47dd71c..8a5e57a8 100644
--- a/plugins/jetpack/_inc/images/image-2x.png
+++ b/plugins/jetpack/_inc/images/image-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/imgedit-icons-2x.png b/plugins/jetpack/_inc/images/imgedit-icons-2x.png
index 155f5411..c9a0f02d 100644
--- a/plugins/jetpack/_inc/images/imgedit-icons-2x.png
+++ b/plugins/jetpack/_inc/images/imgedit-icons-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/jetpack-closebox-icon.png b/plugins/jetpack/_inc/images/jetpack-closebox-icon.png
index 1c014d9c..5f48b493 100644
--- a/plugins/jetpack/_inc/images/jetpack-closebox-icon.png
+++ b/plugins/jetpack/_inc/images/jetpack-closebox-icon.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/list-2x.png b/plugins/jetpack/_inc/images/list-2x.png
index 27a67b86..043b8695 100644
--- a/plugins/jetpack/_inc/images/list-2x.png
+++ b/plugins/jetpack/_inc/images/list-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/logo-2x.png b/plugins/jetpack/_inc/images/logo-2x.png
index 9f7f693d..80d789ee 100644
--- a/plugins/jetpack/_inc/images/logo-2x.png
+++ b/plugins/jetpack/_inc/images/logo-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/logo-small-2x.png b/plugins/jetpack/_inc/images/logo-small-2x.png
index c39fbf9a..2126ab77 100644
--- a/plugins/jetpack/_inc/images/logo-small-2x.png
+++ b/plugins/jetpack/_inc/images/logo-small-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/logo-small.png b/plugins/jetpack/_inc/images/logo-small.png
index 997dbb13..634b5a99 100644
--- a/plugins/jetpack/_inc/images/logo-small.png
+++ b/plugins/jetpack/_inc/images/logo-small.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/logo.png b/plugins/jetpack/_inc/images/logo.png
index 2d49b671..9882b7ad 100644
--- a/plugins/jetpack/_inc/images/logo.png
+++ b/plugins/jetpack/_inc/images/logo.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/media-button-2x.png b/plugins/jetpack/_inc/images/media-button-2x.png
index 8ad6eb4e..1c6b785c 100644
--- a/plugins/jetpack/_inc/images/media-button-2x.png
+++ b/plugins/jetpack/_inc/images/media-button-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/menuicon-sprite-2x.png b/plugins/jetpack/_inc/images/menuicon-sprite-2x.png
index aa9a3680..302b3369 100644
--- a/plugins/jetpack/_inc/images/menuicon-sprite-2x.png
+++ b/plugins/jetpack/_inc/images/menuicon-sprite-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/menuicon-sprite.png b/plugins/jetpack/_inc/images/menuicon-sprite.png
index 3bebcf1e..15a3351a 100644
--- a/plugins/jetpack/_inc/images/menuicon-sprite.png
+++ b/plugins/jetpack/_inc/images/menuicon-sprite.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/module-clouds-2x.png b/plugins/jetpack/_inc/images/module-clouds-2x.png
index 1bab9fb1..905a4307 100644
--- a/plugins/jetpack/_inc/images/module-clouds-2x.png
+++ b/plugins/jetpack/_inc/images/module-clouds-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/module-clouds.png b/plugins/jetpack/_inc/images/module-clouds.png
index 2414fef9..1e0f72d4 100644
--- a/plugins/jetpack/_inc/images/module-clouds.png
+++ b/plugins/jetpack/_inc/images/module-clouds.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/module-icons-sprite-2x.png b/plugins/jetpack/_inc/images/module-icons-sprite-2x.png
index 11f42042..f73023fe 100644
--- a/plugins/jetpack/_inc/images/module-icons-sprite-2x.png
+++ b/plugins/jetpack/_inc/images/module-icons-sprite-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/module-icons-sprite.png b/plugins/jetpack/_inc/images/module-icons-sprite.png
index c6979f67..90a42f83 100644
--- a/plugins/jetpack/_inc/images/module-icons-sprite.png
+++ b/plugins/jetpack/_inc/images/module-icons-sprite.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/press-this-2x.png b/plugins/jetpack/_inc/images/press-this-2x.png
index a335aecb..be6ee74e 100644
--- a/plugins/jetpack/_inc/images/press-this-2x.png
+++ b/plugins/jetpack/_inc/images/press-this-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/publicize.png b/plugins/jetpack/_inc/images/publicize.png
index 428b886c..8cf9ede5 100644
--- a/plugins/jetpack/_inc/images/publicize.png
+++ b/plugins/jetpack/_inc/images/publicize.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/blue-large.png b/plugins/jetpack/_inc/images/rss/blue-large.png
index b4a6c52f..fd623278 100644
--- a/plugins/jetpack/_inc/images/rss/blue-large.png
+++ b/plugins/jetpack/_inc/images/rss/blue-large.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/blue-medium.png b/plugins/jetpack/_inc/images/rss/blue-medium.png
index f64e3541..94110185 100644
--- a/plugins/jetpack/_inc/images/rss/blue-medium.png
+++ b/plugins/jetpack/_inc/images/rss/blue-medium.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/blue-small.png b/plugins/jetpack/_inc/images/rss/blue-small.png
index c281155e..8e4b053b 100644
--- a/plugins/jetpack/_inc/images/rss/blue-small.png
+++ b/plugins/jetpack/_inc/images/rss/blue-small.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/green-large.png b/plugins/jetpack/_inc/images/rss/green-large.png
index 4bf86435..a9c2c83c 100644
--- a/plugins/jetpack/_inc/images/rss/green-large.png
+++ b/plugins/jetpack/_inc/images/rss/green-large.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/green-medium.png b/plugins/jetpack/_inc/images/rss/green-medium.png
index 13304ce2..f8e8fbc0 100644
--- a/plugins/jetpack/_inc/images/rss/green-medium.png
+++ b/plugins/jetpack/_inc/images/rss/green-medium.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/green-small.png b/plugins/jetpack/_inc/images/rss/green-small.png
index 8833c9e6..299905b8 100644
--- a/plugins/jetpack/_inc/images/rss/green-small.png
+++ b/plugins/jetpack/_inc/images/rss/green-small.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/orange-large.png b/plugins/jetpack/_inc/images/rss/orange-large.png
index 966b1c1a..12503492 100644
--- a/plugins/jetpack/_inc/images/rss/orange-large.png
+++ b/plugins/jetpack/_inc/images/rss/orange-large.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/orange-medium.png b/plugins/jetpack/_inc/images/rss/orange-medium.png
index 8f5aaa24..7c47f764 100644
--- a/plugins/jetpack/_inc/images/rss/orange-medium.png
+++ b/plugins/jetpack/_inc/images/rss/orange-medium.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/orange-small.png b/plugins/jetpack/_inc/images/rss/orange-small.png
index 9e0bf22e..4f326d56 100644
--- a/plugins/jetpack/_inc/images/rss/orange-small.png
+++ b/plugins/jetpack/_inc/images/rss/orange-small.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/pink-large.png b/plugins/jetpack/_inc/images/rss/pink-large.png
index 49b94c77..1273b773 100644
--- a/plugins/jetpack/_inc/images/rss/pink-large.png
+++ b/plugins/jetpack/_inc/images/rss/pink-large.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/pink-medium.png b/plugins/jetpack/_inc/images/rss/pink-medium.png
index cd8e957b..feb154c7 100644
--- a/plugins/jetpack/_inc/images/rss/pink-medium.png
+++ b/plugins/jetpack/_inc/images/rss/pink-medium.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/purple-large.png b/plugins/jetpack/_inc/images/rss/purple-large.png
index 1ddb70f0..704765ee 100644
--- a/plugins/jetpack/_inc/images/rss/purple-large.png
+++ b/plugins/jetpack/_inc/images/rss/purple-large.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/purple-medium.png b/plugins/jetpack/_inc/images/rss/purple-medium.png
index 8d375a5f..f785cbb2 100644
--- a/plugins/jetpack/_inc/images/rss/purple-medium.png
+++ b/plugins/jetpack/_inc/images/rss/purple-medium.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/purple-small.png b/plugins/jetpack/_inc/images/rss/purple-small.png
index 75f3c607..d21d59be 100644
--- a/plugins/jetpack/_inc/images/rss/purple-small.png
+++ b/plugins/jetpack/_inc/images/rss/purple-small.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/red-large.png b/plugins/jetpack/_inc/images/rss/red-large.png
index 88d9bf8d..5e03f141 100644
--- a/plugins/jetpack/_inc/images/rss/red-large.png
+++ b/plugins/jetpack/_inc/images/rss/red-large.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/red-medium.png b/plugins/jetpack/_inc/images/rss/red-medium.png
index 838db55b..d01e0d8d 100644
--- a/plugins/jetpack/_inc/images/rss/red-medium.png
+++ b/plugins/jetpack/_inc/images/rss/red-medium.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/red-small.png b/plugins/jetpack/_inc/images/rss/red-small.png
index 85fd61c6..d42b135d 100644
--- a/plugins/jetpack/_inc/images/rss/red-small.png
+++ b/plugins/jetpack/_inc/images/rss/red-small.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/silver-large.png b/plugins/jetpack/_inc/images/rss/silver-large.png
index af67da9d..d10b8849 100644
--- a/plugins/jetpack/_inc/images/rss/silver-large.png
+++ b/plugins/jetpack/_inc/images/rss/silver-large.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/silver-medium.png b/plugins/jetpack/_inc/images/rss/silver-medium.png
index 5559c8c2..34552319 100644
--- a/plugins/jetpack/_inc/images/rss/silver-medium.png
+++ b/plugins/jetpack/_inc/images/rss/silver-medium.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/rss/silver-small.png b/plugins/jetpack/_inc/images/rss/silver-small.png
index 4a41080d..ef8be0eb 100644
--- a/plugins/jetpack/_inc/images/rss/silver-small.png
+++ b/plugins/jetpack/_inc/images/rss/silver-small.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/beautifulmath.png b/plugins/jetpack/_inc/images/screenshots/beautifulmath.png
index eaf8d1d4..3599a425 100644
--- a/plugins/jetpack/_inc/images/screenshots/beautifulmath.png
+++ b/plugins/jetpack/_inc/images/screenshots/beautifulmath.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/carousel.png b/plugins/jetpack/_inc/images/screenshots/carousel.png
index 5bcc94cd..bc56e4da 100644
--- a/plugins/jetpack/_inc/images/screenshots/carousel.png
+++ b/plugins/jetpack/_inc/images/screenshots/carousel.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/comments.png b/plugins/jetpack/_inc/images/screenshots/comments.png
index 86f6530c..04f37ba9 100644
--- a/plugins/jetpack/_inc/images/screenshots/comments.png
+++ b/plugins/jetpack/_inc/images/screenshots/comments.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/contactform.png b/plugins/jetpack/_inc/images/screenshots/contactform.png
index b41760b4..02934a50 100644
--- a/plugins/jetpack/_inc/images/screenshots/contactform.png
+++ b/plugins/jetpack/_inc/images/screenshots/contactform.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/custom-css.png b/plugins/jetpack/_inc/images/screenshots/custom-css.png
index 4be5cb22..1e35ad48 100644
--- a/plugins/jetpack/_inc/images/screenshots/custom-css.png
+++ b/plugins/jetpack/_inc/images/screenshots/custom-css.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/hovercards.png b/plugins/jetpack/_inc/images/screenshots/hovercards.png
index 63977a5b..12205492 100644
--- a/plugins/jetpack/_inc/images/screenshots/hovercards.png
+++ b/plugins/jetpack/_inc/images/screenshots/hovercards.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/likes.png b/plugins/jetpack/_inc/images/screenshots/likes.png
index 1c7670a3..9f5404ac 100644
--- a/plugins/jetpack/_inc/images/screenshots/likes.png
+++ b/plugins/jetpack/_inc/images/screenshots/likes.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/mobile-push-notifications.jpg b/plugins/jetpack/_inc/images/screenshots/mobile-push-notifications.jpg
index 94ca6dd6..d09d3915 100644
--- a/plugins/jetpack/_inc/images/screenshots/mobile-push-notifications.jpg
+++ b/plugins/jetpack/_inc/images/screenshots/mobile-push-notifications.jpg
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/notes.png b/plugins/jetpack/_inc/images/screenshots/notes.png
index 4506db17..bf3a6b99 100644
--- a/plugins/jetpack/_inc/images/screenshots/notes.png
+++ b/plugins/jetpack/_inc/images/screenshots/notes.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/post-by-email.png b/plugins/jetpack/_inc/images/screenshots/post-by-email.png
index b114088c..e63e9a7b 100644
--- a/plugins/jetpack/_inc/images/screenshots/post-by-email.png
+++ b/plugins/jetpack/_inc/images/screenshots/post-by-email.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/publicize.png b/plugins/jetpack/_inc/images/screenshots/publicize.png
index 428b886c..8cf9ede5 100644
--- a/plugins/jetpack/_inc/images/screenshots/publicize.png
+++ b/plugins/jetpack/_inc/images/screenshots/publicize.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/sharing.png b/plugins/jetpack/_inc/images/screenshots/sharing.png
index 9c36d17b..0949b5e4 100644
--- a/plugins/jetpack/_inc/images/screenshots/sharing.png
+++ b/plugins/jetpack/_inc/images/screenshots/sharing.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/shortcodes.png b/plugins/jetpack/_inc/images/screenshots/shortcodes.png
index 8bff1d6d..5434e120 100644
--- a/plugins/jetpack/_inc/images/screenshots/shortcodes.png
+++ b/plugins/jetpack/_inc/images/screenshots/shortcodes.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/shortlinks.png b/plugins/jetpack/_inc/images/screenshots/shortlinks.png
index 2de84771..bfc99cfa 100644
--- a/plugins/jetpack/_inc/images/screenshots/shortlinks.png
+++ b/plugins/jetpack/_inc/images/screenshots/shortlinks.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/spelling.png b/plugins/jetpack/_inc/images/screenshots/spelling.png
index a6986d4f..b28142e5 100644
--- a/plugins/jetpack/_inc/images/screenshots/spelling.png
+++ b/plugins/jetpack/_inc/images/screenshots/spelling.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/stats.png b/plugins/jetpack/_inc/images/screenshots/stats.png
index 836c1392..ceb3fbed 100644
--- a/plugins/jetpack/_inc/images/screenshots/stats.png
+++ b/plugins/jetpack/_inc/images/screenshots/stats.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/subscriptions.png b/plugins/jetpack/_inc/images/screenshots/subscriptions.png
index a1c55630..113800b2 100644
--- a/plugins/jetpack/_inc/images/screenshots/subscriptions.png
+++ b/plugins/jetpack/_inc/images/screenshots/subscriptions.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/tiled-gallery.png b/plugins/jetpack/_inc/images/screenshots/tiled-gallery.png
index 8168590d..0da99eee 100644
--- a/plugins/jetpack/_inc/images/screenshots/tiled-gallery.png
+++ b/plugins/jetpack/_inc/images/screenshots/tiled-gallery.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/vaultpress.png b/plugins/jetpack/_inc/images/screenshots/vaultpress.png
index f1f80c70..64645bc8 100644
--- a/plugins/jetpack/_inc/images/screenshots/vaultpress.png
+++ b/plugins/jetpack/_inc/images/screenshots/vaultpress.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/screenshots/widgets.png b/plugins/jetpack/_inc/images/screenshots/widgets.png
index e0749c62..ad609ae9 100644
--- a/plugins/jetpack/_inc/images/screenshots/widgets.png
+++ b/plugins/jetpack/_inc/images/screenshots/widgets.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/stars-2x.png b/plugins/jetpack/_inc/images/stars-2x.png
index a370aaf6..503c83a0 100644
--- a/plugins/jetpack/_inc/images/stars-2x.png
+++ b/plugins/jetpack/_inc/images/stars-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/status-light-2x.png b/plugins/jetpack/_inc/images/status-light-2x.png
index adff4979..461d9874 100644
--- a/plugins/jetpack/_inc/images/status-light-2x.png
+++ b/plugins/jetpack/_inc/images/status-light-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/status-light.png b/plugins/jetpack/_inc/images/status-light.png
index 9a6665c5..c9ffb7bb 100644
--- a/plugins/jetpack/_inc/images/status-light.png
+++ b/plugins/jetpack/_inc/images/status-light.png
Binary files differ
diff --git a/plugins/jetpack/_inc/images/tb-close-2x.png b/plugins/jetpack/_inc/images/tb-close-2x.png
index 9f5f6b63..9530278d 100644
--- a/plugins/jetpack/_inc/images/tb-close-2x.png
+++ b/plugins/jetpack/_inc/images/tb-close-2x.png
Binary files differ
diff --git a/plugins/jetpack/_inc/jetpack-retina.css b/plugins/jetpack/_inc/jetpack-retina.css
index c5c69ff8..295f6caa 100644
--- a/plugins/jetpack/_inc/jetpack-retina.css
+++ b/plugins/jetpack/_inc/jetpack-retina.css
@@ -1,5 +1,9 @@
/* Retina core icons */
-@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
/* TinyMCE buttons */
.wp_themeSkin .mceToolbar span.mce_undo,
.wp_themeSkin .mceToolbar span.mce_redo,
@@ -36,7 +40,7 @@
.wp_themeSkin .mceToolbar .mceSplitButton .mce_forecolor span.mce_forecolor,
.wp_themeSkin .mceToolbar .mceSplitButton span.mce_numlist,
.wp_themeSkin .mceToolbar .mceSplitButton span.mce_bullist {
- background-image: url('images/wpicons-2x.png');
+ background-image: url(images/wpicons-2x.png);
background-size: 560px 40px;
}
@@ -44,7 +48,7 @@
.view-switch .current #view-switch-list,
.view-switch #view-switch-excerpt,
.view-switch .current #view-switch-excerpt {
- background-image: url('images/list-2x.png');
+ background-image: url(images/list-2x.png);
background-size: 80px 20px;
}
@@ -55,74 +59,76 @@
.imgedit-fliph,
.imgedit-undo,
.imgedit-redo {
- background-image: url('images/imgedit-icons-2x.png');
+ background-image: url(images/imgedit-icons-2x.png);
background-size: 260px 64px;
}
/* Welcome screen close button */
.welcome-panel .welcome-panel-close:before {
- background-image: url('images/xit-2x.gif');
+ background-image: url(images/xit-2x.gif);
background-size: 20px 10px;
}
/* Dismiss tag buttons */
- .tagchecklist span a, #bulk-titles div a {
- background-image: url('images/xit-2x.gif') !important;
+ .tagchecklist span a,
+ #bulk-titles div a {
+ background-image: url(images/xit-2x.gif) !important;
background-size: 20px 10px !important;
}
- .tagchecklist span a:hover, #bulk-titles div a:hover {
- background-image: url('images/xit-2x.gif') !important;
+ .tagchecklist span a:hover,
+ #bulk-titles div a:hover {
+ background-image: url(images/xit-2x.gif) !important;
background-size: 20px 10px !important;
}
/* Pointer dismiss button */
.wp-pointer-buttons a.close::before {
- background-image: url('images/xit-2x.gif');
- background-size: 20px 10px;
+ background-image: url(images/xit-2x.gif);
+ background-size: 20px 10px;
}
/* Pointer icon */
.wp-pointer-content h3::before {
- background-image: url('images/icon-pointer-flag-2x.png');
+ background-image: url(images/icon-pointer-flag-2x.png);
background-size: 36px 37px;
}
/* Pointer arrow */
.wp-pointer-arrow {
- background-image: url('images/arrow-pointer-blue-2x.png') !important;
+ background-image: url(images/arrow-pointer-blue-2x.png) !important;
background-size: 30px 60px !important;
}
/* Screen options links */
#screen-meta-links a.show-settings {
- background-image: url('images/arrows-2x.png') !important;
+ background-image: url(images/arrows-2x.png) !important;
background-size: 15px 123px !important;
}
body.admin-color-classic #screen-meta-links a.show-settings {
- background-image: url('images/arrows-vs-2x.png') !important;
+ background-image: url(images/arrows-vs-2x.png) !important;
}
-
+
/* Collapse button divs */
#collapse-button div {
- background-image: url('images/arrows-2x.png') !important;
+ background-image: url(images/arrows-2x.png) !important;
background-size: 15px 123px !important;
}
body.admin-color-classic #collapse-button div {
- background-image: url('images/arrows-vs-2x.png') !important;
+ background-image: url(images/arrows-vs-2x.png) !important;
}
/* Metabox handle arrows */
.meta-box-sortables .postbox:hover .handlediv {
- background-image: url('images/arrows-2x.png') !important;
+ background-image: url(images/arrows-2x.png) !important;
background-size: 15px 123px !important;
}
body.admin-color-classic .meta-box-sortables .postbox:hover .handlediv {
- background-image: url('images/arrows-vs-2x.png') !important;
+ background-image: url(images/arrows-vs-2x.png) !important;
}
/* Date button */
.curtime #timestamp {
- background-image: url('images/date-button-2x.gif') !important;
+ background-image: url(images/date-button-2x.gif) !important;
background-size: 16px 16px;
display: inline-block;
height: 16px;
@@ -133,77 +139,88 @@
padding-top: 12px;
height: 0;
width: 12px;
- background: transparent url('images/comment-grey-bubble-2x.png') no-repeat center center;
+ background: transparent url(images/comment-grey-bubble-2x.png) no-repeat center center;
background-size: 12px 12px;
}
.post-com-count {
- background-image: url('images/bubble_bg-2x.png') !important;
+ background-image: url(images/bubble_bg-2x.png) !important;
background-size: 18px 100px;
}
/* Post sorting indicator */
.sorting-indicator {
- background-image: url('images/sort-2x.gif');
+ background-image: url(images/sort-2x.gif);
background-size: 14px 4px;
}
/* Widget arrows */
.sidebar-name-arrow {
- background-image: url('images/arrows-2x.png') !important;
+ background-image: url(images/arrows-2x.png) !important;
background-size: 15px 123px !important;
}
+
body.admin-color-classic .sidebar-name-arrow {
- background-image: url('images/arrows-vs-2x.png') !important;
+ background-image: url(images/arrows-vs-2x.png) !important;
}
+
.sidebar-name:hover .sidebar-name-arrow {
- background-image: url('images/arrows-dark-2x.png') !important;
+ background-image: url(images/arrows-dark-2x.png) !important;
}
+
body.admin-color-classic .sidebar-name:hover .sidebar-name-arrow {
- background-image: url('images/arrows-dark-vs-2x.png') !important;
+ background-image: url(images/arrows-dark-vs-2x.png) !important;
}
+
.widget-top a.widget-action {
- background-image: url('images/arrows-2x.png') !important;
+ background-image: url(images/arrows-2x.png) !important;
background-size: 15px 123px !important;
}
+
body.admin-color-classic .widget-top a.widget-action {
- background-image: url('images/arrows-vs-2x.png') !important;
+ background-image: url(images/arrows-vs-2x.png) !important;
}
+
.widget-top a.widget-action:hover {
- background-image: url('images/arrows-dark-2x.png') !important;
+ background-image: url(images/arrows-dark-2x.png) !important;
}
+
body.admin-color-classic .widget-top a.widget-action:hover {
- background-image: url('images/arrows-dark-vs-2x.png') !important;
+ background-image: url(images/arrows-dark-vs-2x.png) !important;
}
/* Menu editor item arrows */
.item-edit {
- background-image: url('images/arrows-2x.png') !important;
+ background-image: url(images/arrows-2x.png) !important;
background-size: 15px 123px !important;
}
+
body.admin-color-classic .item-edit {
- background-image: url('images/arrows-vs-2x.png') !important;
+ background-image: url(images/arrows-vs-2x.png) !important;
}
+
.item-edit:hover {
- background-image: url('images/arrows-dark-2x.png') !important;
+ background-image: url(images/arrows-dark-2x.png) !important;
background-size: 15px 123px !important;
}
+
body.admin-color-classic .item-edit:hover {
- background-image: url('images/arrows-dark-vs-2x.png') !important;
+ background-image: url(images/arrows-dark-vs-2x.png) !important;
}
/* Plugin install star ratings */
div.star-holder {
- background-image: url('images/stars-2x.png');
+ background-image: url(images/stars-2x.png);
background-size: 21px 37px;
}
+
div.star-holder .star-rating {
- background-image: url('images/stars-2x.png');
+ background-image: url(images/stars-2x.png);
background-size: 21px 37px;
}
/* Press This bookmarklet icon */
.pressthis a span {
- background-image: url('images/press-this-2x.png');
+ background-image: url(images/press-this-2x.png);
background-size: 24px 20px;
}
@@ -212,7 +229,7 @@
padding-top: 15px;
width: 15px;
height: 0;
- background: url('images/media-button-2x.png') no-repeat center center;
+ background: url(images/media-button-2x.png) no-repeat center center;
background-size: 15px 15px;
}
@@ -221,28 +238,28 @@
padding-top: 20px;
width: 20px;
height: 0;
- background: url('images/atdbuttontr-2x.png') no-repeat center center;
+ background: url(images/atdbuttontr-2x.png) no-repeat center center;
background-size: 20px 20px;
}
/* Resize editor */
#post-body .wp_themeSkin .mceStatusbar a.mceResize {
- background-image: url('images/resize-2x.gif') !important;
+ background-image: url(images/resize-2x.gif) !important;
background-size: 11px 11px !important;
}
/* MCE dropdowns */
.wp_themeSkin .mceListBox .mceOpen span, .wp_themeSkin .mceSplitButton a.mceOpen {
- background-image: url("images/down_arrow-2x.gif") !important;
+ background-image: url(images/down_arrow-2x.gif) !important;
background-size: 10px 20px;
}
-
+
/* Img overlay buttons */
#wp_editimgbtn, #wp_delimgbtn, #wp_editgallery, #wp_delgallery {
padding-top: 24px !important;
height: 0;
width: 24px;
- background: url("images/delete-2x.png") no-repeat center center !important;
+ background: url(images/delete-2x.png) no-repeat center center !important;
background-size: 24px 24px;
}
@@ -254,40 +271,40 @@
}
#wp_editimgbtn, #wp_editgallery {
- background: #eee url("images/image-2x.png") no-repeat center center !important;
+ background: #eee url(images/image-2x.png) no-repeat center center !important;
}
#wp_delimgbtn, #wp_delgallery {
- background: #eee url("images/delete-2x.png") no-repeat center center !important;
+ background: #eee url(images/delete-2x.png) no-repeat center center !important;
}
-
+
/* AJAX loading spinners */
img.ajax-loading, img.ajax-feedback {
width: 16px;
height: 0;
padding-top: 19px !important;
- background: url("images/wpspin_light-2x.gif") no-repeat center center !important;
+ background: url(images/wpspin_light-2x.gif) no-repeat center center !important;
background-size: 16px 16px;
}
/* Align buttons (in image properties in the media library) */
.image-align-none-label {
- background: url('images/align-none-2x.png') no-repeat center left;
+ background: url(images/align-none-2x.png) no-repeat center left;
background-size: 21px 15px;
}
.image-align-left-label {
- background: url('images/align-left-2x.png') no-repeat center left;
+ background: url(images/align-left-2x.png) no-repeat center left;
background-size: 22px 15px;
}
.image-align-center-label {
- background: url('images/align-center-2x.png') no-repeat center left;
+ background: url(images/align-center-2x.png) no-repeat center left;
background-size: 21px 15px;
}
.image-align-right-label {
- background: url('images/align-right-2x.png') no-repeat center left;
+ background: url(images/align-right-2x.png) no-repeat center left;
background-size: 22px 15px;
}
@@ -345,88 +362,88 @@
/* Uploader close button */
#TB_closeWindowButton img {
- background: url('images/tb-close-2x.png') no-repeat center center;
+ background: url(images/tb-close-2x.png) no-repeat center center;
padding-top: 15px;
width: 15px;
height: 0;
background-size: 15px 15px;
}
- td.media-icon img[src$='wp-includes/images/crystal/archive.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/archive.png'] {
- background: url('images/archive-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/archive.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/archive.png"] {
+ background: url(images/archive-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
background-size: 46px 60px;
}
- td.media-icon img[src$='wp-includes/images/crystal/audio.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/audio.png'] {
- background: url('images/audio-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/audio.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/audio.png"] {
+ background: url(images/audio-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
background-size: 46px 60px;
}
- td.media-icon img[src$='wp-includes/images/crystal/code.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/code.png'] {
- background: url('images/code-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/code.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/code.png"] {
+ background: url(images/code-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
background-size: 46px 60px;
}
- td.media-icon img[src$='wp-includes/images/crystal/default.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/default.png'] {
- background: url('images/default-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/default.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/default.png"] {
+ background: url(images/default-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
background-size: 46px 60px;
}
- td.media-icon img[src$='wp-includes/images/crystal/document.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/document.png'] {
- background: url('images/document-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/document.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/document.png"] {
+ background: url(images/document-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
background-size: 46px 60px;
}
- td.media-icon img[src$='wp-includes/images/crystal/interactive.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/interactive.png'] {
- background: url('images/interactive-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/interactive.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/interactive.png"] {
+ background: url(images/interactive-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
background-size: 46px 60px;
}
- td.media-icon img[src$='wp-includes/images/crystal/spreadsheet.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/spreadsheet.png'] {
- background: url('images/spreadsheet-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/spreadsheet.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/spreadsheet.png"] {
+ background: url(images/spreadsheet-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
background-size: 46px 60px;
}
- td.media-icon img[src$='wp-includes/images/crystal/text.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/text.png'] {
- background: url('images/text-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/text.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/text.png"] {
+ background: url(images/text-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
background-size: 46px 60px;
}
- td.media-icon img[src$='wp-includes/images/crystal/video.png'],
- td.A1B1 img[src$='wp-includes/images/crystal/video.png'] {
- background: url('images/video-2x.png') no-repeat center center;
+ td.media-icon img[src$="wp-includes/images/crystal/video.png"],
+ td.A1B1 img[src$="wp-includes/images/crystal/video.png"] {
+ background: url(images/video-2x.png) no-repeat center center;
padding-top: 60px;
width: 46px;
height: 0;
@@ -434,23 +451,23 @@
}
.farbtastic .marker {
- background-image: url('images/marker-2x.png');
+ background-image: url(images/marker-2x.png);
background-size: 17px 17px;
}
.farbtastic .wheel {
- background-image: url('images/wheel-2x.png');
+ background-image: url(images/wheel-2x.png);
background-size: 195px 195px;
}
.farbtastic .overlay {
- background-image: url('images/mask-2x.png');
+ background-image: url(images/mask-2x.png);
background-size: 101px 101px;
}
/* Generic admin menu icon */
- #adminmenu img[src$='wp-admin/images/generic.png'] {
- background: url('images/generic-2x.png') no-repeat center center;
+ #adminmenu img[src$="wp-admin/images/generic.png"] {
+ background: url(images/generic-2x.png) no-repeat center center;
padding-top: 25px;
width: 16px;
height: 0;
@@ -463,7 +480,7 @@
.clearlooks2 .mceMed,
.clearlooks2 .mceMax,
.wp-dialog .ui-dialog-titlebar-close {
- background-image: url('images/buttons-2x.gif') !important;
+ background-image: url(images/buttons-2x.gif) !important;
background-size: 116px 48px !important;
}
}
diff --git a/plugins/jetpack/_inc/jetpack-rtl.css b/plugins/jetpack/_inc/jetpack-rtl.css
index 45c676b4..f1fad500 100644
--- a/plugins/jetpack/_inc/jetpack-rtl.css
+++ b/plugins/jetpack/_inc/jetpack-rtl.css
@@ -1,128 +1,120 @@
- #jp-header #jp-clouds {
- background-position: -632px 100%;
- }
- #jp-header.small #jp-clouds {
- background-position: -425px 100%;
- }
-
- #jp-header #jp-clouds #jp-disconnect {
- float: left;
- margin: -35px 0 0 25px;
- text-align: left;
- }
-
- #jp-header #jp-clouds #jp-disconnect a {
- background-position: 100% 90%;
- padding: 4px 30px 3px 10px;
- }
- #jp-header #jp-clouds #jp-disconnect a:hover {
- background-position: 100% 3%;
- }
-
- #jp-header h3 {
- background-position: top right;
- right: 25px;
- left: auto;
- }
-
- #jp-header p {
- right: 390px;
- left: auto;
- text-align: right;
- }
-
- #jp-info {
- margin: 0 28px 0 12px;
- }
-
- #jp-info p {
- float:right;
- }
-
- #jp-info a.jp-button {
- float: left;
- margin: 8px 20px 0 0;
- }
-
- .jp-connect { padding: 10px 0 5px !important; }
-
- #jetpack-settings > .jetpack-message { margin: 10px 15px 10px 13px }
-
- .jetpack-message .squeezer {
- text-align: right;
- }
- .jetpack-message h4 {
- margin: 0 0 10px 10px;
- }
-
- .more-info {
- margin: 0 15px 5px 12px;
- background: transparent url( images/header-clouds-sm.png ) bottom right repeat-x;
- }
- .more-info .jp-close {
- left: 0;
- right: auto;
- padding: 0 6px 0 4px;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
- -moz-border-radius-topright: 0;
- -moz-border-radius-bottomright: 0;
- -webkit-border-top-left-radius: 0;
- -webkit-border-bottom-left-radius: 0;
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
- }
-
- .more-info div.jp-info-img {
- float: left;
- margin: 0 20px 0 30px;
- }
-
+#jp-header #jp-clouds {
+ background-position: -632px 100%;
+}
+
+#jp-header.small #jp-clouds {
+ background-position: -425px 100%;
+}
+
+#jp-header #jp-clouds #jp-disconnect {
+ float: left;
+ margin: -35px 0 0 25px;
+ text-align: left;
+}
+
+#jp-header #jp-clouds #jp-disconnect a {
+ background-position: 100% 90%;
+ padding: 4px 30px 3px 10px;
+}
+
+#jp-header #jp-clouds #jp-disconnect a:hover {
+ background-position: 100% 3%;
+}
+
+#jp-header h3 {
+ background-position: top right;
+ right: 25px;
+ left: auto;
+}
+
+#jp-header p {
+ right: 390px;
+ left: auto;
+ text-align: right;
+}
+
+#jp-info {
+ margin: 0 28px 0 12px;
+}
+
+#jp-info p {
+ float:right;
+}
+
+#jp-info a.jp-button {
+ float: left;
+ margin: 8px 20px 0 0;
+}
+
+.jp-connect {
+ padding: 10px 0 5px !important;
+}
+
+#jetpack-settings > .jetpack-message {
+ margin: 10px 15px 10px 13px;
+}
+
+.jetpack-message .squeezer {
+ text-align: right;
+}
+
+.jetpack-message h4 {
+ margin: 0 0 10px 10px;
+}
+
+.more-info {
+ margin: 0 15px 5px 12px;
+ background: transparent url(images/header-clouds-sm.png) bottom right repeat-x;
+}
+
+.more-info .jp-close {
+ left: 0;
+ right: auto;
+ padding: 0 6px 0 4px;
+ border-radius: 3px;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.more-info div.jp-info-img {
+ float: left;
+ margin: 0 20px 0 30px;
+}
+
.jetpack-module {
float: right;
margin: 0 15px 15px 0;
padding: 15px 15px 35px 0;
}
- .jetpack-module div.module-image {
- float: left;
- margin: 0 10px 5px 0;
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- border-radius: 0;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topleft: 5px;
- border-top-right-radius: 5px;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
- border-bottom-right-radius: 5px;
- }
-
- .jetpack-module div.module-image p {
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- border-radius: 0;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
- border-bottom-right-radius: 5px;
- }
-
-
- .jetpack-module .jetpack-module-actions {
- right: 15px;
- left: auto;
- }
-
- .placeholder h3 {
- margin-left: 15px;
- margin-right: auto;
- }
-
- #jp-footer .automattic {
- padding-right: 3px;
- padding-left: 0;
- }
-
- #jp-footer .automattic span {
- margin: 0 1px 0 5px;
- }
+
+.jetpack-module div.module-image {
+ float: left;
+ margin: 0 10px 5px 0;
+ border-radius: 0;
+ border-top-right-radius: 5px;
+ border-bottom-right-radius: 5px;
+}
+
+.jetpack-module div.module-image p {
+ border-radius: 0;
+ border-bottom-right-radius: 5px;
+}
+
+.jetpack-module .jetpack-module-actions {
+ right: 15px;
+ left: auto;
+}
+
+.placeholder h3 {
+ margin-left: 15px;
+ margin-right: auto;
+}
+
+#jp-footer .automattic {
+ padding-right: 3px;
+ padding-left: 0;
+}
+
+#jp-footer .automattic span {
+ margin: 0 1px 0 5px;
+}
diff --git a/plugins/jetpack/_inc/jetpack.css b/plugins/jetpack/_inc/jetpack.css
index b684f7c7..9c2c977d 100644
--- a/plugins/jetpack/_inc/jetpack.css
+++ b/plugins/jetpack/_inc/jetpack.css
@@ -1,439 +1,566 @@
+/*
+ * Consolidate the font-family declarations:
+ */
+
+#jp-header p,
+#jp-info a.jp-button,
+.jetpack-message h4,
+.jetpack-message h5,
+.jetpack-message p a.button-primary,
+.jetpack-activated h3,
+.jetpack-activated p,
+.jetpack-module div.module-image p,
+.jetpack-module h3,
+.jetpack-module .jetpack-module-actions a,
+#jp-settings-screen h3,
+.jp-survey h4,
+.jetpack-install-container p a.button-connector {
+ font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", Verdana, "Bitstream Vera Sans", sans-serif;
+}
+
+#jp-info p,
+.more-info p,
+.more-info ul,
+.jetpack-module-description p {
+ font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif;
+}
+
+/*
+ * Jetpack:
+ */
+
+/* Force the menu not to be sticky, so we can color the arrow. */
+.toplevel_page_jetpack.admin-color-mp6.sticky-menu #adminmenuwrap,
+body[class*=" jetpack_page_jetpack_"].admin-color-mp6.sticky-menu #adminmenuwrap {
+ position: relative;
+ z-index: auto;
+ top: 0;
+}
+
+.toplevel_page_jetpack.admin-color-mp6 ul#adminmenu a.wp-has-current-submenu:after,
+.toplevel_page_jetpack.admin-color-mp6 ul#adminmenu > li.current > a.current:after,
+body[class*=" jetpack_page_jetpack_"].admin-color-mp6 ul#adminmenu a.wp-has-current-submenu:after,
+body[class*=" jetpack_page_jetpack_"].admin-color-mp6 ul#adminmenu > li.current > a.current:after {
+ border-right-color:#8fad4b;
+}
+
+.toplevel_page_jetpack.jetpack-disconnected #wpwrap,
+body[class*=" jetpack_page_jetpack_"].jetpack-disconnected #wpwrap {
+ background: url(images/header-clouds.png) -150px -60px repeat-x;
+}
+
+.toplevel_page_jetpack.jetpack-disconnected.admin-color-mp6 #wpwrap,
+body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.admin-color-mp6 #wpwrap {
+ background-position: -143px -60px;
+}
+
+.toplevel_page_jetpack.jetpack-disconnected.folded #wpwrap,
+body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.folded #wpwrap {
+ background-position: -263px -60px;
+}
+
+.toplevel_page_jetpack.jetpack-disconnected.admin-color-mp6.folded #wpwrap,
+body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.admin-color-mp6.folded #wpwrap {
+ background-position: -257px -60px;
+}
+
+.toplevel_page_jetpack.jetpack-connected #wpwrap,
+body[class*=" jetpack_page_jetpack_"].jetpack-connected #wpwrap {
+ background: url(images/header-clouds-small.png) 45px 0 repeat-x;
+}
+
+.toplevel_page_jetpack.jetpack-connected.admin-color-mp6 #wpwrap,
+body[class*=" jetpack_page_jetpack_"].jetpack-connected.admin-color-mp6 #wpwrap {
+ background-position: 52px 0;
+}
+
+.toplevel_page_jetpack.jetpack-connected.folded #wpwrap,
+body[class*=" jetpack_page_jetpack_"].jetpack-connected.folded #wpwrap {
+ background-position: -68px 0;
+}
+
+.toplevel_page_jetpack.jetpack-connected.admin-color-mp6.folded #wpwrap,
+body[class*=" jetpack_page_jetpack_"].jetpack-connected.admin-color-mp6.folded #wpwrap {
+ background-position: -62px 0;
+}
+
+@media only screen and (max-width: 900px) {
+
+ .toplevel_page_jetpack.jetpack-disconnected.auto-fold #wpwrap,
+ body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.auto-fold #wpwrap {
+ background-position: -263px -60px;
+ }
+
+ .toplevel_page_jetpack.jetpack-disconnected.admin-color-mp6.auto-fold #wpwrap,
+ body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.admin-color-mp6.auto-fold #wpwrap {
+ background-position: -257px -60px;
+ }
+
+ .toplevel_page_jetpack.jetpack-connected.auto-fold #wpwrap,
+ body[class*=" jetpack_page_jetpack_"].jetpack-connected.auto-fold #wpwrap {
+ background-position: -68px 0;
+ }
+
+ .toplevel_page_jetpack.jetpack-connected.admin-color-mp6.auto-fold #wpwrap,
+ body[class*=" jetpack_page_jetpack_"].jetpack-connected.admin-color-mp6.auto-fold #wpwrap {
+ background-position: -62px 0;
+ }
+
+}
+
+.toplevel_page_jetpack.screen-meta-wrap {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ z-index: 2;
+}
+
#jp-header {
min-width: 741px;
z-index: 0;
margin: 30px 0 -30px 0;
}
- #jp-header.small {
- margin-bottom: 50px;
+
+#jp-header.small {
+ margin: 20px 0 50px;
+}
+
+#jp-header #jp-clouds {
+ position: relative;
+ padding-top: 110px;
+}
+
+#jp-header.small #jp-clouds {
+ padding: 50px 0 0 0;
+ height: 70px;
+}
+
+#jp-header #jp-clouds #jp-disconnectors {
+ font-size: 12px;
+ color: #fff;
+ float: right;
+ margin-top: -35px;
+ text-align: left;
+ position: relative;
+ left: -45px;
+}
+
+#jp-header #jp-clouds .jp-disconnect a {
+ background: #8caa46 url(images/status-light.png) 3px 85% no-repeat;
+ display: inline-block;
+ position: relative;
+ width: 100%;
+ height: 1.7em;
+ overflow: hidden;
+ padding: 4px 0 3px 30px;
+ margin: 0 -20px 3px 0;
+ color: #fff;
+ text-decoration: none;
+ border: 1px solid #7a943d;
+ border-radius: 5px;
+ box-shadow: inset 0 0 2px rgba(255, 255, 255, 0.4);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
+}
+
+#jp-header #jp-clouds .jp-disconnect a:hover {
+ background: #8caa46 url(images/status-light.png) 3px -2% no-repeat;
+ background-color: #839f40;
+ border-color: #6a8037;
+}
+
+#jp-header #jp-clouds .jp-disconnect div {
+ position: relative;
+ line-height: 1.7em;
+ height: 1.7em;
+}
+
+#jp-header #jp-clouds .jp-disconnect a:hover div,
+#jp-header #jp-clouds .jp-disconnect a.clicked div {
+ top: -1.7em;
+}
+
+/* Retina Header Clouds & Status Light */
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
+ .toplevel_page_jetpack.jetpack-disconnected #wpwrap,
+ body[class*=" jetpack_page_jetpack_"].jetpack-disconnected #wpwrap {
+ background-image: url(images/header-clouds-2x.png);
+ background-size: 1600px 400px;
}
- #jp-header #jp-clouds {
- position: relative;
- background: transparent url( images/header-clouds.png ) -315px 100% repeat-x;
- padding-top: 110px;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
+ .toplevel_page_jetpack.jetpack-connected #wpwrap,
+ body[class*=" jetpack_page_jetpack_"].jetpack-connected #wpwrap {
+ background-image: url(images/header-clouds-small-2x.png);
+ background-size: 980px 140px;
}
- #jp-header.small #jp-clouds {
- background: transparent url( images/header-clouds-small.png ) -120px 100% repeat-x;
- padding: 50px 0 0 0;
- height: 70px;
- }
-
-
- #jp-header #jp-clouds #jp-disconnectors {
- font-size: 12px;
- color: #fff;
- float: right;
- margin-top: -35px;
- text-align: left;
- position: relative;
- left: -45px;
- }
-
- #jp-header #jp-clouds .jp-disconnect a {
- background: #8caa46 url( images/status-light.png ) 3px 85% no-repeat;
- display: inline-block;
- position: relative;
- width: 100%;
- height: 1.7em;
- overflow: hidden;
- padding: 4px 0 3px 30px;
- margin: 0 -20px 3px 0;
- color: #fff;
- text-decoration: none;
- border: 1px solid #7a943d;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- -moz-box-shadow: inset 0 0 2px rgba( 255, 255, 255, 0.4 );
- -webkit-box-shadow: inset 0 0 2px rgba( 255, 255, 255, 0.4 );
- box-shadow: inset 0 0 2px rgba( 255, 255, 255, 0.4 );
- text-shadow: 0px -1px 0px rgba( 0,0,0,0.3 );
- }
- #jp-header #jp-clouds .jp-disconnect a:hover {
- background: #8caa46 url( images/status-light.png ) 3px -2% no-repeat;
- background-color: #839f40;
- border-color: #6a8037;
- }
-
- #jp-header #jp-clouds .jp-disconnect div {
- position: relative;
- line-height: 1.7em;
- height: 1.7em;
- }
-
- #jp-header #jp-clouds .jp-disconnect a:hover div,
- #jp-header #jp-clouds .jp-disconnect a.clicked div {
- top: -1.7em;
- }
-
- /* Retina Header Clouds & Status Light */
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- #jp-header #jp-clouds {
- background: transparent url( images/header-clouds-2x.png ) -315px 100% repeat-x;
- background-size:1600px 400px;
- }
- #jp-header.small #jp-clouds {
- background: transparent url( images/header-clouds-small-2x.png ) -120px 100% repeat-x;
- background-size:980px 140px;
- }
-
- #jp-header #jp-clouds .jp-disconnect a {
- background: #8caa46 url( images/status-light-2x.png ) 3px 85% no-repeat;
- background-size:25px 57px;
- }
- #jp-header #jp-clouds .jp-disconnect a:hover {
- background: #8caa46 url( images/status-light-2x.png ) 3px -2% no-repeat;
- background-size:25px 57px;
- }
+
+ #jp-header #jp-clouds .jp-disconnect a {
+ background-image: url(images/status-light-2x.png);
+ background-size: 25px 57px;
+ }
+
+ #jp-header #jp-clouds .jp-disconnect a:hover {
+ background-image: url(images/status-light-2x.png);
+ background-size: 25px 57px;
}
+}
+
+#jp-header h3 {
+ position: relative;
+ background: transparent url(images/logo.png) top left no-repeat;
+ width: 252px;
+ height: 200px;
+ overflow: hidden;
+ text-indent: -999em;
+ top: -95px;
+ left: 25px;
+ margin: 0;
+ padding: 0;
+}
+
+#jp-header.small h3 {
+ background: transparent url(images/logo-small.png) top left no-repeat;
+ width: 149px;
+ height: 120px;
+ top: -35px;
+}
+
+/* Retina Logo */
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
#jp-header h3 {
- position: relative;
- background: transparent url( images/logo.png ) top left no-repeat;
- width: 252px;
- height: 200px;
- overflow: hidden;
- text-indent: -999em;
- top: -95px;
- left: 25px;
- margin: 0;
- padding: 0;
+ background-image: url(images/logo-2x.png);
+ background-size: 250px 200px;
}
- #jp-header.small h3 {
- background: transparent url( images/logo-small.png ) top left no-repeat;
- width: 149px;
- height: 120px;
- top: -35px;
- }
-
- /* Retina Logo */
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- #jp-header h3 {
- background: transparent url( images/logo-2x.png ) top left no-repeat;
- background-size:250px 200px;
- }
- #jp-header.small h3 {
- background: transparent url( images/logo-small-2x.png ) top left no-repeat;
- background-size:150px 120px;
- }
+
+ #jp-header.small h3 {
+ background-image: url(images/logo-small-2x.png);
+ background-size: 150px 120px;
}
+}
+#jp-header p {
+ position: absolute;
+ left: 390px;
+ text-align: left;
+ top: 30px;
+ width: 48%;
+ color: #fff;
+ font-size: 25px;
+ line-height: 130%;
+ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
+ -webkit-font-smoothing: antialiased;
+}
- #jp-header p {
- position: absolute;
- left: 390px;
- text-align: left;
- top: 30px;
- width: 48%;
- color: #fff;
- font-size: 25px;
- line-height: 130%;
- text-shadow: 0px 1px 1px rgba(0,0,0,0.5);
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- -webkit-font-smoothing: antialiased;
- }
+#jp-info {
+ position: relative;
+ overflow: visible;
+ z-index: 50;
+ margin: 0 12px 0 28px;
+ min-width: 780px;
+}
- #jp-info {
- position: relative;
- overflow: visible;
- z-index: 50;
- margin: 0 12px 0 28px;
- min-width: 780px;
- }
+#jp-info p {
+ font-size: 17px;
+ line-height: 150%;
+ text-shadow: 0 1px 0 #fff;
+ color: #666;
+ margin: 0 0 40px;
+ float: left;
+ width: 58%;
+}
- #jp-info p {
- font-size: 17px;
- line-height: 150%;
- text-shadow: 0px 1px 0px #fff;
- font-family: Georgia,"Times New Roman","Bitstream Charter",Times,serif;
- color: #666;
- margin: 0 0 40px;
- float:left;
- width: 58%;
- }
- #jp-info p.small {
- font-size: 14px;
- }
-
- #jp-info a.jp-button {
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- float: right;
- margin: 8px 0 0 20px;
- display: inline-block;
- background: #69acce;
- -moz-box-shadow: inset 0 0 2px #fff, 0 1px 5px rgba(0,0,0,0.3);
- -webkit-box-shadow: inset 0 0 2px #fff, 0 1px 5px rgba(0,0,0,0.3);
- box-shadow: inset 0 0 2px #fff, 0 1px 5px rgba(0,0,0,0.3);
- padding: 12px 20px;
- border: 1px solid #2a8cba;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- line-height: 100%;
- color: #fff;
- text-align: center;
- font-size: 20px;
- font-weight: bold;
- text-decoration: none;
- text-shadow: 0px 1px 2px rgba( 0,0,0,0.5);
- -webkit-transition-duration: .3s;
- -moz-transition-duration: .3s;
- cursor: pointer;
- }
- #jp-info a.jp-button:hover, #jp-info a.jp-button:active {
- background-color: #f0a000;
- border-color: #c87800;
- -webkit-transition-duration: .3s;
- outline: none;
- -moz-box-shadow: inset 0 0 2px #fff, 0 1px 7px rgba(240,160,0,0.5);
- -webkit-box-shadow: inset 0 0 2px #fff, 0 1px 7px rgba(240,160,0,0.5);
- box-shadow: inset 0 0 2px #fff, 0 1px 7spx rgba(240,160,0,0.5);
- }
+#jp-info p.small {
+ font-size: 14px;
+}
+
+#jp-info a.jp-button {
+ float: right;
+ margin: 8px 0 0 20px;
+ display: inline-block;
+ background: #69acce;
+ box-shadow: inset 0 0 2px #fff,
+ 0 1px 5px rgba(0, 0, 0, 0.3);
+ padding: 12px 20px;
+ border: 1px solid #2a8cba;
+ border-radius: 5px;
+ line-height: 100%;
+ color: #fff;
+ text-align: center;
+ font-size: 20px;
+ font-weight: bold;
+ text-decoration: none;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
+ -webkit-transition-duration: 0.3s;
+ transition-duration: 0.3s;
+ cursor: pointer;
+}
+
+#jp-info a.jp-button:hover,
+#jp-info a.jp-button:active {
+ background-color: #f0a000;
+ border-color: #c87800;
+ outline: none;
+ box-shadow: inset 0 0 2px #fff,
+ 0 1px 7px rgba(240, 160, 0, 0.5);
+}
.jetpack-message {
position: relative;
z-index: 100;
border: 1px solid #2a8cba !important;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
border-radius: 3px;
- background: url( images/alertbox-clouds.png ) 100% 100% no-repeat;
+ background: url(images/alertbox-clouds.png) 100% 100% no-repeat;
background-color: #6aafcf !important;
- -webkit-box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
- -moz-box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
- box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
+ box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.04);
padding: 18px 90px 8px 15px !important;
overflow: hidden;
line-height: 180%;
}
/* Retina alertbox clouds */
-@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- .jetpack-message {
- background: url( images/alertbox-clouds-2x.png ) 100% 100% no-repeat;
- background-size:95px 55px;
- }
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
+ .jetpack-message {
+ background-image: url(images/alertbox-clouds-2x.png);
+ background-size: 95px 55px;
+ }
+
}
- .jp-connect { padding: 10px 0 5px !important; }
+.jp-connect {
+ padding: 10px 0 5px !important;
+}
- #jetpack-settings > .jetpack-message { margin: 10px 13px 10px 15px }
+#jetpack-settings > .jetpack-message {
+ margin: 10px 13px 10px 15px;
+}
- .jetpack-message .squeezer {
- max-width: 940px;
- margin: 0 0 2px;
- padding: 0 10px;
- text-align: left;
- overflow: hidden;
- }
- .jetpack-message h4 {
- margin: 0 10px 10px 0;
- font-size: 18px;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- font-weight: normal;
- color: #fff;
- text-shadow: 0px 1px 1px rgba(0,0,0,0.4);
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- display: inline-block;
- }
+.jetpack-message .squeezer {
+ max-width: 940px;
+ margin: 0 0 2px;
+ padding: 0 10px;
+ text-align: left;
+ overflow: hidden;
+}
- .jetpack-message h5 {
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- margin: 0;
- }
+.jetpack-message h4 {
+ margin: 0 10px 10px 0;
+ font-size: 18px;
+ font-weight: normal;
+ color: #fff;
+ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
+ border-radius: 5px;
+ display: inline-block;
+}
- .jetpack-message .squeezer a, .jetpack-message .squeezer a:visited {
- color: #fff;
- text-decoration: underline;
- }
+.jetpack-message h5 {
+ margin: 0;
+}
- .jetpack-message .squeezer a:hover {
- color: #f0a000;
- }
+.jetpack-message .squeezer a,
+.jetpack-message .squeezer a:visited {
+ color: #fff;
+ text-decoration: underline;
+}
- .jetpack-message code, .jetpack-err p {
- background: rgba( 0,0,0,0.2 );
- font-size: 14px;
- padding: 3px 5px !important;
- text-shadow: 0px 1px 1px rgba(0,0,0,0.4);
- color: #fff;
- }
+.jetpack-message .squeezer a:hover {
+ color: #f0a000;
+}
- .jetpack-message p {
- margin: -1px 0 0 0 !important;
- padding: 0;
- display: inline-block;
- }
- .jetpack-err p {
- overflow: hidden;
- margin-bottom: 10px !important;
- }
-
- .jetpack-message p a.button-primary {
- font-size: 16px !important;
- display: inline-block;
- padding: 8px 15px;
- color: #fff;
- text-align: center;
- font-size: 20px;
- text-decoration: none;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- border: 1px solid #8caa46;
- background: #b4d278;
- -moz-box-shadow: inset 0 0 2px rgba( 255,255,255,1), 0 1px 1px rgba( 0,0,0,0.1 );
- -webkit-box-shadow: inset 0 0 2px rgba( 255,255,255,1), 0 1px 1px rgba( 0,0,0,0.1 );
- box-shadow: inset 0 0 2px rgba( 255,255,255,1), 0 1px 1px rgba( 0,0,0,0.1 );
- text-shadow: 0px -1px 0px rgba( 0,0,0,0.3);
- -webkit-transition-duration: .3s;
- -moz-transition-duration: .3s;
- cursor: pointer;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- }
- .jetpack-message p a.button-primary:hover, .jetpack-message p a.button-primary:active {
- background-color: #f0a000;
- border-color: #c87800;
- -webkit-transition-duration: .3s;
- outline: none;
- }
-
- .inline-message p strong { display: block; }
+.jetpack-message code, .jetpack-err p {
+ background: rgba(0, 0, 0, 0.2);
+ font-size: 14px;
+ padding: 3px 5px !important;
+ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
+ color: #fff;
+}
+
+.jetpack-message p {
+ margin: -1px 0 0 0 !important;
+ padding: 0;
+ display: inline-block;
+}
+
+.jetpack-err p {
+ overflow: hidden;
+ margin-bottom: 10px !important;
+}
+
+.jetpack-message p a.button-primary {
+ font-size: 16px !important;
+ display: inline-block;
+ padding: 8px 15px;
+ color: #fff;
+ text-align: center;
+ font-size: 20px;
+ text-decoration: none;
+ border-radius: 5px;
+ border: 1px solid #8caa46;
+ background: #b4d278;
+ box-shadow: inset 0 0 2px #fff,
+ 0 1px 1px rgba(0, 0, 0, 0.1);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
+ -webkit-transition-duration: 0.3s;
+ transition-duration: 0.3s;
+ cursor: pointer;
+}
+
+.jetpack-message p a.button-primary:hover,
+.jetpack-message p a.button-primary:active {
+ background-color: #f0a000;
+ border-color: #c87800;
+ outline: none;
+}
+
+.inline-message p strong {
+ display: block;
+}
+
+.more-info {
+ position: relative;
+ top: -5px;
+ margin: 0 15px 5px 15px;
+ height: 230px; /* Have to set height otherwise slideDown() doesn't work. */
+ padding-right: 15px !important;
+ padding-bottom: 15px;
+ clear: both;
+ overflow: visible !important;
+ color: #666 !important;
+ background: transparent url(images/module-clouds.png) bottom left repeat-x;
+ background-color: #f0f0f0 !important;
+ border-color: #dcdcdc !important;
+ text-shadow: 0 1px 0 #fff;
+ box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.05),
+ 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+/* Retina moreinfo bg clouds */
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
.more-info {
- position: relative;
- top: -5px;
- margin: 0 15px 5px 15px;
- height: 230px; /* Have to set height otherwise slideDown() doesn't work. */
- padding-right: 15px !important;
- padding-bottom: 15px;
- clear: both;
- overflow: visible !important;
- color: #666 !important;
- background: transparent url( images/module-clouds.png ) bottom left repeat-x;
- background-color: #f0f0f0 !important;
- border-color: #dcdcdc !important;
- text-shadow: 0px 1px 0px #fff;
- -webkit-box-shadow: inset 0 0 20px rgba(0,0,0,0.05), 0 1px 2px rgba( 0,0,0,0.1 );
- -moz-box-shadow: inset 0 0 20px rgba(0,0,0,0.05), 0 1px 2px rgba( 0,0,0,0.1 );
- box-shadow: inset 0 0 20px rgba(0,0,0,0.05), 0 1px 2px rgba( 0,0,0,0.1 );
+ background-image: url(images/module-clouds-2x.png);
+ background-size: 980px 140px;
}
- /* Retina moreinfo bg clouds */
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- .more-info {
- background: transparent url( images/module-clouds-2x.png ) bottom left repeat-x;
- background-size:980px 140px;
- }
+}
+
+.more-info h4 {
+ padding: 0;
+ background: none;
+ font-weight: normal;
+ color: #000;
+ font-size: 19px;
+ text-shadow: 0 1px 0 #fff;
+}
+
+.more-info h5 {
+ margin-left: 0;
+ font-size: 12px !important;
+}
+
+.more-info .arrow {
+ position: absolute;
+ width: 29px;
+ height: 18px;
+ top: -16px;
+ left: 0;
+ background: url(images/arrow.png) top left no-repeat;
+}
+
+.more-info .arrow:after {
+ display: none;
+}
+
+/* Retina module more info arrow */
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
+ .more-info .arrow {
+ background-image: url(images/arrow-2x.png);
+ background-size: 29px 16px;
}
+}
+
+.more-info p {
+ margin: 0 0 10px 0 !important;
+ font-size: 14px;
+ line-height: 150%;
+ display: block;
+}
+
+.more-info ul {
+ font-size: 14px;
+ line-height: 150%;
+}
+
+.more-info li {
+ list-style-type: disc;
+ list-style-position: inside;
+}
+
+.more-info code {
+ background: rgba(0, 0, 0, 0.05);
+ font-size: 12px;
+ padding: 1px;
+ text-shadow: none;
+ color: #555;
+}
+
+.more-info .jp-close {
+ position: absolute;
+ top: 18px;
+ right: 0;
+ background: #888;
+ background: rgba(0, 0, 0, 0.4);
+ color: #fff;
+ font-size: 14px !important;
+ height: 22px;
+ line-height: 20px;
+ padding: 0 6px 0 6px;
+ font-weight: bold !important;
+ border-radius: 3px;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ cursor: pointer;
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
+}
+
+.more-info .jp-close:hover {
+ background: #69acce;
+}
+
+.more-info div.jp-info-img {
+ float: right;
+ width: 320px;
+ margin: 0 30px 0 20px;
+}
- .more-info h4 {
- padding: 0;
- background: none;
- font-weight: normal;
- color: #000;
- font-size: 19px;
- text-shadow: 0px 1px 0px #fff;
- }
-
- .more-info h5 {
- margin-left: 0;
- font-size: 12px !important;
- }
- .more-info .arrow {
- position: absolute;
- width: 29px;
- height: 18px;
- top: -16px;
- left: 0;
- background: url( images/arrow.png ) top left no-repeat;
- }
-
- /* Retina module more info arrow */
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- .more-info .arrow {
- background: url( images/arrow-2x.png ) top left no-repeat;
- background-size:29px 16px;
- }
- }
-
- .more-info p {
- margin: 0 0 10px 0 !important;
- font-size: 14px;
- font-family: Georgia,"Times New Roman","Bitstream Charter",Times,serif;
- line-height: 150%;
- display: block;
- }
-
- .more-info ul {
- font-size: 14px;
- font-family: Georgia,"Times New Roman","Bitstream Charter",Times,serif;
- line-height: 150%;
- }
-
- .more-info li {
- list-style-type: disc;
- list-style-position: inside;
- }
-
- .more-info code {
- background: rgba( 0,0,0,0.05 );
- font-size: 12px;
- padding: 1px;
- text-shadow: none;
- color: #555;
- }
-
- .more-info .jp-close {
- position: absolute;
- top: 18px;
- right: 0;
- background: #888;
- background: rgba(0,0,0,0.4);
- color: #fff;
- font-size: 14px !important;
- height: 22px;
- line-height: 20px;
- padding: 0 6px 0 6px;
- font-weight: bold !important;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
- -moz-border-radius-topright: 0;
- -moz-border-radius-bottomright: 0;
- -webkit-border-top-right-radius: 0;
- -webkit-border-bottom-right-radius: 0;
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- cursor: pointer;
- text-shadow: 0 1px 0 rgba(0,0,0,0.2);
- }
- .more-info .jp-close:hover {
- background: #69acce;
- }
-
- .more-info div.jp-info-img {
- float: right;
- width: 320px;
- margin: 0 30px 0 20px;
- }
-
- .more-info img.jp-info-img {
- padding: 3px;
- background: rgba( 255, 255, 255, 0.65 );
- border: 5px solid #ddd;
- }
+.more-info img.jp-info-img {
+ padding: 3px;
+ background: rgba(255, 255, 255, 0.65);
+ border: 5px solid #ddd;
+}
.jetpack-activated {
- background: #fffff5 url( images/jp-enabled-bg.jpg ) top left repeat-x !important;
+ background: #fffff5 url(images/jp-enabled-bg.jpg) top left repeat-x !important;
height: 154px;
padding: 60px 0 0 200px !important;
position: relative;
@@ -442,59 +569,55 @@
z-index: 5;
position: relative;
}
- .jetpack-activated h3 {
- position: relative;
- z-index: 5;
- color: #444;
- font-size: 42px;
- font-weight: bold;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- margin: 0;
- padding: 0;
- background: none;
- display: block;
- text-transform: uppercase;
- }
- .jetpack-activated p {
- position: relative;
- z-index: 3;
- top: 3px;
- left: 10px;
- font-size: 16px;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- font-weight: normal;
- color: #666;
- background: rgba( 255, 255, 255, 0.75 );
- padding: 7px 10px 6px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- display: inline-block;
- }
- .jetpack-activated .jetpack {
- position: absolute;
- top: 0;
- left: 0;
- width: 238px;
- height: 214px;
- background: url( images/jp-enabled-jetpack.jpg ) top left no-repeat;
- z-index: 2;
- }
- .jetpack-activated .clouds {
- position: absolute;
- right: 0;
- bottom: 0;
- width: 566px;
- height: 214px;
- background: url( images/jp-enabled-clouds.png ) bottom left no-repeat;
- z-index: 0;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomright: 5px;
- border-bottom-right-radius: 5px;
- -webkit-box-shadow: inset -7px -7px 10px rgba( 0,0,0,0.05 );
- -moz-box-shadow: inset -7px -7px 10px rgba( 0,0,0,0.05 );
- box-shadow: inset -7px -7px 10px rgba( 0,0,0,0.05 );
- }
+
+.jetpack-activated h3 {
+ position: relative;
+ z-index: 5;
+ color: #444;
+ font-size: 42px;
+ font-weight: bold;
+ margin: 0;
+ padding: 0;
+ background: none;
+ display: block;
+ text-transform: uppercase;
+}
+
+.jetpack-activated p {
+ position: relative;
+ z-index: 3;
+ top: 3px;
+ left: 10px;
+ font-size: 16px;
+ font-weight: normal;
+ color: #666;
+ background: rgba(255, 255, 255, 0.75);
+ padding: 7px 10px 6px;
+ border-radius: 5px;
+ display: inline-block;
+}
+
+.jetpack-activated .jetpack {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 238px;
+ height: 214px;
+ background: url(images/jp-enabled-jetpack.jpg) top left no-repeat;
+ z-index: 2;
+}
+
+.jetpack-activated .clouds {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ width: 566px;
+ height: 214px;
+ background: url(images/jp-enabled-clouds.png) bottom left no-repeat;
+ z-index: 0;
+ border-bottom-right-radius: 5px;
+ box-shadow: inset -7px -7px 10px rgba(0, 0, 0, 0.05);
+}
p.jp-help {
padding: 10px 0 15px;
@@ -515,346 +638,397 @@ p.jp-help {
max-height: 220px;
margin: 0 0 15px 15px;
border: 1px solid #dedede;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
border-radius: 3px;
background: #fff;
padding: 15px 0 35px 15px;
- -webkit-box-shadow: inset 0 1px 0 #fff, inset 0 0 20px rgba(0,0,0,0.05), 0 1px 2px rgba( 0,0,0,0.1 );
- -moz-box-shadow: inset 0 1px 0 #fff, inset 0 0 20px rgba(0,0,0,0.05), 0 1px 2px rgba( 0,0,0,0.1 );
- box-shadow: inset 0 1px 0 #fff, inset 0 0 20px rgba(0,0,0,0.05), 0 1px 2px rgba( 0,0,0,0.1 );
- -webkit-transition-duration: .4s;
- -moz-transition-duration: .4s
+ box-shadow: inset 0 1px 0 #fff,
+ inset 0 0 20px rgba(0, 0, 0, 0.05),
+ 0 1px 2px rgba(0, 0, 0, 0.1);
+ -webkit-transition-duration: 0.4s;
+ transition-duration: 0.4s;
}
+
/*
- .jetpack-module:hover {
- border-color: #bbb;
- -webkit-box-shadow: 0 1px 2px rgba( 0,0,0,0.2 );
- -moz-box-shadow: 0 1px 2px rgba( 0,0,0,0.2 );
- box-shadow: 0 1px 2px rgba( 0,0,0,0.2 );
- -webkit-transition-duration: .4s;
- -moz-transition-duration: .4s
- }
+.jetpack-module:hover {
+ border-color: #bbb;
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+ -webkit-transition-duration: 0.4s;
+ transition-duration: 0.4s;
+}
*/
+
+.jetpack-module div.module-image {
+ float: right;
+ margin: 0 0 5px 10px;
+ padding: 60px 0 0;
+ background: #cbe0a1;
+ width: 80px;
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ background-repeat: no-repeat;
+ background-image: url(images/module-icons-sprite.png);
+ background-size: 2705px 50px; /* remember to update this every time a new module is added! */
+}
+
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
.jetpack-module div.module-image {
- float: right;
- margin: 0 0 5px 10px;
- padding: 60px 0 0;
- background: #cbe0a1;
- width: 80px;
- -webkit-border-top-left-radius: 3px;
- -moz-border-radius-topleft: 3px;
- border-top-left-radius: 3px;
- -webkit-border-bottom-left-radius: 3px;
- -moz-border-radius-bottomleft: 3px;
- border-bottom-left-radius: 3px;
- background-repeat: no-repeat;
- background-image: url( images/module-icons-sprite.png );
- background-size: 2555px 50px; /* remember to update this every time a new module is added! */
+ background-image: url(images/module-icons-sprite-2x.png);
}
+}
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- .jetpack-module div.module-image {
- background-image: url( images/module-icons-sprite-2x.png );
- }
- }
+#stats.jetpack-module div.module-image {
+ background-position: -510px 5px;
+}
- #stats.jetpack-module div.module-image {
- background-position: -510px 5px;
- }
- #comments.jetpack-module div.module-image {
- background-position: -1210px 5px;
- }
- #subscriptions.jetpack-module div.module-image {
- background-position: -1009px 5px;
- }
- #sharedaddy.jetpack-module div.module-image {
- background-position: -710px 5px;
- }
- #after-the-deadline.jetpack-module div.module-image {
- background-position: -308px 5px;
- }
- #vaultpress.jetpack-module div.module-image {
- background-position: -910px 5px;
- }
- #gravatar-hovercards.jetpack-module div.module-image {
- background-position: -410px 5px;
- }
- #contact-form.jetpack-module div.module-image {
- background-position: -1107px 5px;
- }
- #shortlinks.jetpack-module div.module-image {
- background-position: -108px 5px;
- }
- #shortcodes.jetpack-module div.module-image {
- background-position: -608px 5px;
- }
- #latex.jetpack-module div.module-image {
- background-position: -208px 5px;
- }
- #widgets.jetpack-module div.module-image {
- background-position: -5px 5px;
- }
- #enhanced-distribution.jetpack-module div.module-image {
- background-position: -808px 5px;
- }
- #carousel.jetpack-module div.module-image {
- background-position: -1325px 5px;
- }
- #custom-css.jetpack-module div.module-image {
- background-position: -1459px 5px;
- }
- #minileven.jetpack-module div.module-image {
- background-position: -1570px 5px;
- }
- #notes.jetpack-module div.module-image {
- background-position: -1806px 5px;
- }
- #json-api.jetpack-module div.module-image {
- background-position: -1689px 5px;
- }
- #mobile-push.jetpack-module div.module-image {
- background-position: -1925px 5px;
- }
- #publicize.jetpack-module div.module-image {
- background-position: -2136px 5px;
- }
- #post-by-email.jetpack-module div.module-image {
- background-position: -2025px 5px;
- }
- #infinite-scroll.jetpack-module div.module-image {
- background-position: -2230px 5px;
- }
- #photon.jetpack-module div.module-image {
- background-position: -2320px 5px;
- }
- #tiled-gallery.jetpack-module div.module-image {
- background-position: -2400px 5px;
- }
-
- #likes.jetpack-module div.module-image {
- background-position: -2471px 5px;
- }
-
- .jetpack-module div.module-image p {
- background-color: #b4d278;
- color: #fff;
- text-shadow: 1px 1px 0px rgba(0,0,0,0.2);
- text-align: center;
- margin: 0;
- padding: 0;
- clear: both;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- font-weight: bold;
- -webkit-font-smoothing: antialiased;
- -webkit-border-bottom-left-radius: 2px;
- -moz-border-radius-bottomleft: 2px;
- border-bottom-left-radius: 2px;
- }
-
- .jetpack-new-module div.module-image p {
- background-color: #f5bd4d;
- }
-
- .jetpack-updated-module div.module-image p {
- background-color: #6aafcf;
- }
-
- .jetpack-new-module:hover div.module-image p {
- background-color: #b4d278;
- }
-
- .jetpack-updated-module:hover div.module-image p {
- background-color: #b4d278;
- }
-
- .jetpack-new-module:hover div.module-image span.module-image-free,
- .jetpack-updated-module:hover div.module-image span.module-image-free {
- display: inline !important;
- }
-
- .jetpack-new-module:hover div.module-image span.module-image-badge,
- .jetpack-updated-module:hover div.module-image span.module-image-badge {
- display: none;
- }
-
- .jetpack-toggle {
- float: right;
- padding: 2px 4px 4px;
- }
- .jetpack-toggle a {
- text-decoration: none;
- font-weight: bold;
- font-size: 180%;
- color: #bbb;
- }
-
- .jetpack-active .jetpack-toggle-button:hover { color: #b90000; }
-
- .jetpack-module h3 {
- line-height: 1.1;
- margin: 0;
- padding: 0;
- font-size: 17px;
- font-weight: normal;
- font-style: normal;
- color: #000;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- }
+#comments.jetpack-module div.module-image {
+ background-position: -1210px 5px;
+}
- .jetpack-module-description p {
- line-height: 150%;
- font-size: 12px;
- font-family: Georgia,"Times New Roman","Bitstream Charter",Times,serif;
- margin-bottom: 20px;
- color: #666;
- }
+#subscriptions.jetpack-module div.module-image {
+ background-position: -1009px 5px;
+}
- .jetpack-module .jetpack-module-actions {
- position: absolute;
- bottom: 20px;
- left: 15px;
- background: #fff;
- display: block;
- }
+#sharedaddy.jetpack-module div.module-image {
+ background-position: -710px 5px;
+}
- .jetpack-module .jetpack-module-actions a {
- position: relative;
- font-weight: bold;
- color: #888;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- }
+#after-the-deadline.jetpack-module div.module-image {
+ background-position: -308px 5px;
+}
- .jetpack-inactive {
- border-color: #eee;
- cursor: pointer;
- }
- .jetpack-inactive *, jetpack-inactive:hover * { -webkit-transition-duration: .4s; -moz-transition-duration: .4s }
+#vaultpress.jetpack-module div.module-image {
+ background-position: -910px 5px;
+}
+
+#gravatar-hovercards.jetpack-module div.module-image {
+ background-position: -410px 5px;
+}
+
+#contact-form.jetpack-module div.module-image {
+ background-position: -1107px 5px;
+}
+
+#shortlinks.jetpack-module div.module-image {
+ background-position: -108px 5px;
+}
+
+#shortcodes.jetpack-module div.module-image {
+ background-position: -608px 5px;
+}
+
+#latex.jetpack-module div.module-image {
+ background-position: -208px 5px;
+}
+
+#widgets.jetpack-module div.module-image {
+ background-position: -5px 5px;
+}
+
+#enhanced-distribution.jetpack-module div.module-image {
+ background-position: -808px 5px;
+}
+
+#carousel.jetpack-module div.module-image {
+ background-position: -1325px 5px;
+}
+
+#custom-css.jetpack-module div.module-image {
+ background-position: -1459px 5px;
+}
+
+#minileven.jetpack-module div.module-image {
+ background-position: -1570px 5px;
+}
+
+#notes.jetpack-module div.module-image {
+ background-position: -1806px 5px;
+}
+
+#json-api.jetpack-module div.module-image {
+ background-position: -1689px 5px;
+}
+
+#mobile-push.jetpack-module div.module-image {
+ background-position: -1925px 5px;
+}
+
+#publicize.jetpack-module div.module-image {
+ background-position: -2136px 5px;
+}
+
+#post-by-email.jetpack-module div.module-image {
+ background-position: -2025px 5px;
+}
+
+#infinite-scroll.jetpack-module div.module-image {
+ background-position: -2230px 5px;
+}
+
+#photon.jetpack-module div.module-image {
+ background-position: -2320px 5px;
+}
+
+#tiled-gallery.jetpack-module div.module-image {
+ background-position: -2400px 5px;
+}
+
+#likes.jetpack-module div.module-image {
+ background-position: -2471px 5px;
+}
+
+#debug.jetpack-module div.module-image {
+ background-position: -2550px 5px;
+}
+
+#omnisearch.jetpack-module div.module-image {
+ background-position: -2625px 5px;
+}
+
+.jetpack-module div.module-image p {
+ background-color: #b4d278;
+ color: #fff;
+ text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
+ text-align: center;
+ margin: 0;
+ padding: 0;
+ clear: both;
+ font-weight: bold;
+ -webkit-font-smoothing: antialiased;
+ border-bottom-left-radius: 2px;
+}
- .jetpack-inactive h3, .jetpack-inactive p, .jetpack-inactive span {
- color: #ccc;
- }
+.jetpack-new-module div.module-image p {
+ background-color: #f5bd4d;
+}
- .jetpack-inactive .jetpack-configure-button { display: none; }
- .jetpack-inactive div.module-image {
- opacity: 0.6;
- }
+.jetpack-updated-module div.module-image p {
+ background-color: #6aafcf;
+}
- .jetpack-inactive .jetpack-module-description p a {
- color: #92b8d0;
- }
- .jetpack-inactive:hover .jetpack-module-description p a {
- color: #5590b7;
- }
+.jetpack-new-module:hover div.module-image p {
+ background-color: #b4d278;
+}
+.jetpack-updated-module:hover div.module-image p {
+ background-color: #b4d278;
+}
- .jetpack-inactive:hover {
- border-color: #ddd;
- }
+.jetpack-new-module:hover div.module-image span.module-image-free,
+.jetpack-updated-module:hover div.module-image span.module-image-free {
+ display: inline !important;
+}
- .jetpack-inactive:hover h3, .jetpack-inactive:hover p, .jetpack-inactive:hover span {
- color: #aaa;
- }
+.jetpack-new-module:hover div.module-image span.module-image-badge,
+.jetpack-updated-module:hover div.module-image span.module-image-badge {
+ display: none;
+}
- .jetpack-inactive:hover div.module-image {
- opacity: 0.75;
- }
+.jetpack-toggle {
+ float: right;
+ padding: 2px 4px 4px;
+}
- .placeholder {
- border-color: #eee !important;
- cursor: default !important;
+.jetpack-toggle a {
+ text-decoration: none;
+ font-weight: bold;
+ font-size: 180%;
+ color: #bbb;
+}
+
+.jetpack-active .jetpack-toggle-button:hover {
+ color: #b90000;
+}
+
+.jetpack-module h3 {
+ line-height: 1.1;
+ margin: 0;
+ padding: 0;
+ font-size: 17px;
+ font-weight: normal;
+ font-style: normal;
+ color: #000;
+}
+
+.jetpack-module-description p {
+ line-height: 150%;
+ font-size: 12px;
+ margin-bottom: 20px;
+ color: #666;
+}
+
+.jetpack-module .jetpack-module-actions {
+ position: absolute;
+ bottom: 20px;
+ left: 15px;
+ background: #fff;
+ display: block;
+}
+
+.jetpack-module .jetpack-module-actions a {
+ position: relative;
+ font-weight: bold;
+ color: #888;
+}
+
+.jetpack-inactive {
+ border-color: #eee;
+ cursor: pointer;
+}
+
+.jetpack-inactive *,
+jetpack-inactive:hover * {
+ -webkit-transition-duration: 0.4s;
+ transition-duration: 0.4s;
+}
+
+.jetpack-inactive h3, .jetpack-inactive p, .jetpack-inactive span {
+ color: #ccc;
+}
+
+.jetpack-inactive .jetpack-configure-button {
+ display: none;
+}
+
+.jetpack-inactive div.module-image {
+ opacity: 0.6;
+}
+
+.jetpack-inactive .jetpack-module-description p a {
+ color: #92b8d0;
+}
+
+.jetpack-inactive:hover .jetpack-module-description p a {
+ color: #5590b7;
+}
+
+.jetpack-inactive:hover {
+ border-color: #ddd;
+}
+
+.jetpack-inactive:hover h3,
+.jetpack-inactive:hover p,
+.jetpack-inactive:hover span {
+ color: #aaa;
+}
+
+.jetpack-inactive:hover div.module-image {
+ opacity: 0.75;
+}
+
+.placeholder {
+ border-color: #eee !important;
+ cursor: default !important;
+}
+
+.placeholder h3 {
+ color: #dadada;
+ margin-top: 55px;
+ text-align: center;
+ background: transparent url(images/icon-comingsoon.png) top center no-repeat;
+ padding: 40px 0 0 0;
+ margin-right: 15px;
+ box-shadow: none;
+}
+
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
+ .placeholder h3 {
+ background-image: url(images/icon-comingsoon-2x.png);
+ background-size: 32px 32px;
}
- .placeholder h3 {
- color: #dadada;
- margin-top: 55px;
- text-align: center;
- background: transparent url(images/icon-comingsoon.png) top center no-repeat;
- padding: 40px 0 0 0;
- margin-right: 15px;
- box-shadow: none;
- }
-
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- .placeholder h3 {
- background: transparent url(images/icon-comingsoon-2x.png) top center no-repeat;
- background-size:32px 32px;
- }
- }
+}
#jp-settings-screen {
margin: 0 25px;
}
- #jp-settings-screen h3 {
- font-size: 18px;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
- color: #555;
- padding-bottom: 20px;
- border-bottom: 1px solid #eee;
- }
+
+#jp-settings-screen h3 {
+ font-size: 18px;
+ color: #555;
+ padding-bottom: 20px;
+ border-bottom: 1px solid #eee;
+}
p#news-sub {
text-align: center;
}
#jp-footer {
- background: url( images/footer-clouds.png ) top center no-repeat;
+ background: url(images/footer-clouds.png) top center no-repeat;
margin: 30px 0;
padding-top: 60px;
text-align: center;
}
-@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- #jp-footer {
- background: url( images/footer-clouds-2x.png ) top center no-repeat;
- background-size:700px 150px;
- }
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
+ #jp-footer {
+ background-image: url(images/footer-clouds-2x.png);
+ background-size: 700px 150px;
+ }
+
}
+#jp-footer .automattic {
+ color: #999;
+ font-size: 10px;
+ line-height: 15px;
+ text-transform: uppercase;
+ letter-spacing: 3px;
+ padding-left: 3px;
+}
- #jp-footer .automattic {
- color: #999;
- font-size: 10px;
- line-height: 15px;
- text-transform: uppercase;
- letter-spacing: 3px;
- padding-left: 3px;
- }
+#jp-footer .automattic span {
+ text-indent: -999em;
+ overflow: hidden;
+ background: url(images/automattic.png) center top no-repeat;
+ display: inline-block;
+ width: 165px;
+ vertical-align: top;
+ margin: 0 5px 0 1px;
+ line-height: 14px;
+ height: 14px;
+ filter: alpha(opacity=40);
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
+ opacity: 0.5;
+}
- #jp-footer .automattic span {
- text-indent: -999em;
- overflow: hidden;
- background: url( images/automattic.png ) center top no-repeat;
- display: inline-block;
- width: 165px;
- vertical-align: top;
- margin: 0 5px 0 1px;
- line-height: 14px;
- height: 14px;
- filter: alpha(opacity=40);
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
- opacity: 0.5;
- }
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- #jp-footer .automattic span {
- background: url( images/automattic-2x.png ) center top no-repeat;
- background-size:165px 14px;
- }
- }
-
- #jp-footer p.small {
- font-size: 11px;
- color: #ccc;
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
+ #jp-footer .automattic span {
+ background-image: url(images/automattic-2x.png);
+ background-size: 165px 14px;
}
- #jp-footer .small a {
- text-decoration: none;
- }
+}
- #jp-footer .small a:hover {
- text-decoration: underline;
- }
+#jp-footer p.small {
+ font-size: 11px;
+ color: #ccc;
+}
+
+#jp-footer .small a {
+ text-decoration: none;
+}
+
+#jp-footer .small a:hover {
+ text-decoration: underline;
+}
#jetpack-configuration code {
font-size: 14px;
@@ -864,7 +1038,11 @@ p#news-sub {
clear: both;
}
-.error, .updated { position: relative; z-index: 100; }
+.error,
+.updated {
+ position: relative;
+ z-index: 100;
+}
.toplevel_page_jetpack .wrap {
max-width: 983px;
@@ -880,29 +1058,24 @@ p#news-sub {
position: relative;
z-index: 100;
border: 1px solid #ccc !important;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
border-radius: 3px;
background-color: #efefef !important;
- -webkit-box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
- -moz-box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
- box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
+ box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.04);
padding: 18px 90px 8px 15px !important;
overflow: hidden;
line-height: 180%;
}
-#jetpack-settings > .jp-survey { margin: 10px 13px 40px 15px }
+#jetpack-settings > .jp-survey {
+ margin: 10px 13px 40px 15px;
+}
.jp-survey h4 {
margin: 0;
font-size: 18px;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
font-weight: normal;
color: #333;
text-shadow: 0 1px 0 #fff;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
border-radius: 5px;
display: block;
float: left;
@@ -942,50 +1115,40 @@ p#news-sub {
width: 16px;
height: 16px;
text-indent: -9999px;
- background: transparent url( images/alertbox-closeicon.png ) no-repeat center center;
+ background: transparent url(images/alertbox-closeicon.png) center center no-repeat;
border: 0 none;
- -moz-border-radius: 0 0 0 5px;
- -webkit-border-radius: 0 0 0 5px;
- -o-border-radius: 0 0 0 5px;
- -ms-border-radius: 0 0 0 5px;
border-radius: 0 0 0 5px;
- -moz-box-shadow: none;
- -webkit-box-shadow: none;
box-shadow: none;
- -webkit-transition-duration: .3s;
- -moz-transition-duration: .3s;
- -o-transition-duration: .3s;
- -ms-transition-duration: .3s;
- transition-duration: .3s;
+ -webkit-transition-duration: 0.3s;
+ transition-duration: 0.3s;
cursor: pointer;
}
-@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- .jetpack-close-button {
- background: transparent url( images/alertbox-closeicon-2x.png ) no-repeat center center;
- background-size:16px 16px;
- }
+@media only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (min-device-pixel-ratio: 1.5) {
+
+ .jetpack-close-button {
+ background-image: url(images/alertbox-closeicon-2x.png);
+ background-size: 16px 16px;
+ }
+
}
.jetpack-close-button:hover {
background-color: #fff;
border: 0 none;
outline: none;
- -webkit-transition-duration: .3s;
- -moz-transition-duration: .3s;
- -o-transition-duration: .3s;
- -ms-transition-duration: .3s;
- transition-duration: .3s;
+ -webkit-transition-duration: 0.3s;
+ transition-duration: 0.3s;
}
.jetpack-close-button:active {
background-color: #efefef;
border: 0 none;
- -webkit-transition-duration: .3s;
- -moz-transition-duration: .3s;
- -o-transition-duration: .3s;
- -ms-transition-duration: .3s;
- transition-duration: .3s;
+ -webkit-transition-duration: 0.3s;
+ transition-duration: 0.3s;
}
.jetpack-wrap-container {
@@ -1002,17 +1165,13 @@ p#news-sub {
position: absolute;
bottom: 5px;
right: 15px;
- font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
float: right;
display: inline-block;
background: #b4d278;
- -moz-box-shadow: inset 0 0 2px #fff, 0 1px 5px rgba(0,0,0,0.3);
- -webkit-box-shadow: inset 0 0 2px #fff, 0 1px 5px rgba(0,0,0,0.3);
- box-shadow: inset 0 0 2px #fff, 0 1px 5px rgba(0,0,0,0.3);
+ box-shadow: inset 0 0 2px #fff,
+ 0 1px 5px rgba(0, 0, 0, 0.3);
padding: 8px 15px;
border: 1px solid #2a8cba;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
border-radius: 5px;
line-height: 1.3;
color: #fff;
@@ -1020,26 +1179,23 @@ p#news-sub {
font-size: 16px;
font-weight: bold;
text-decoration: none;
- text-shadow: 0px 1px 2px rgba( 0,0,0,0.5);
- -webkit-transition-duration: .3s;
- -moz-transition-duration: .3s;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
+ -webkit-transition-duration: 0.3s;
+ transition-duration: 0.3s;
cursor: pointer;
}
-.jetpack-install-container p a.button-connector:hover, .jetpack-install-container p a.button-connector:active {
+.jetpack-install-container p a.button-connector:hover,
+.jetpack-install-container p a.button-connector:active {
background-color: #f0a000;
border-color: #c87800;
- -webkit-transition-duration: .3s;
outline: none;
- -moz-box-shadow: inset 0 0 2px #fff, 0 1px 7px rgba(240,160,0,0.5);
- -webkit-box-shadow: inset 0 0 2px #fff, 0 1px 7px rgba(240,160,0,0.5);
- box-shadow: inset 0 0 2px #fff, 0 1px 7spx rgba(240,160,0,0.5);
+ box-shadow: inset 0 0 2px #fff,
+ 0 1px 7px rgba(240, 160, 0, 0.5);
}
.jetpack-inline-error, .jetpack-inline-message {
- padding: .5em 1em .5em 1em;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
+ padding: 0.5em 1em 0.5em 1em;
border-radius: 3px;
border-width: 1px;
border-style: solid;
diff --git a/plugins/jetpack/_inc/jetpack.js b/plugins/jetpack/_inc/jetpack.js
index 6ef9de8d..4d70053d 100644
--- a/plugins/jetpack/_inc/jetpack.js
+++ b/plugins/jetpack/_inc/jetpack.js
@@ -80,6 +80,7 @@ jetpack = {
}
} );
+ jQuery( '#screen-meta, #screen-meta-links' ).wrapAll( '<div class="screen-meta-wrap" />' );
},
level_modules: function() {
diff --git a/plugins/jetpack/_inc/jquery.inview.js b/plugins/jetpack/_inc/jquery.inview.js
index 45f71c4c..b581903a 100644
--- a/plugins/jetpack/_inc/jquery.inview.js
+++ b/plugins/jetpack/_inc/jquery.inview.js
@@ -73,14 +73,14 @@
visiblePartX,
visiblePartY,
visiblePartsMerged;
-
+
// for the case where 'display:none' is used in place of 'visibility:hidden'
// count and sum the above items to get and move closer to the correct values
// IMPORTANT :: insert element into container empty
if($element.css('display') == 'none')
{
var parentElement = $element.parent();
-
+
elementOffset.top = parentElement.offset().top;
elementOffset.left = parentElement.offset().left;
elementSize.height = parentElement.height();
@@ -98,7 +98,7 @@
if (!viewportOffset || !viewportSize) {
return;
}
-
+
if (element.offsetWidth >= 0 && element.offsetHeight >= 0 && element.style.display != "none" &&
elementOffset.top + elementSize.height > viewportOffset.top &&
elementOffset.top < viewportOffset.top + viewportSize.height &&
@@ -124,7 +124,7 @@
$(w).bind("scroll resize", function() {
viewportSize = viewportOffset = null;
});
-
+
// IE < 9 scrolls to focused elements without firing the "scroll" event
if (!documentElement.addEventListener && documentElement.attachEvent) {
documentElement.attachEvent("onfocusin", function() {
diff --git a/plugins/jetpack/_inc/jquery.jetpack-resize.js b/plugins/jetpack/_inc/jquery.jetpack-resize.js
index e1adb22d..1c3cc87c 100644
--- a/plugins/jetpack/_inc/jquery.jetpack-resize.js
+++ b/plugins/jetpack/_inc/jquery.jetpack-resize.js
@@ -60,7 +60,7 @@
if ( 'undefined' === typeof $.fn.Jetpack ) {
/**
* Dispatches calls to the correct namespace
- *
+ *
* @param string namespace
* @param ...
* @return mixed|jQuery (chainable)
@@ -81,7 +81,7 @@
/**
* Defines the Jetpack.resizeable() namespace.
* See below for non-trivial definition for browsers with postMessage.
- */
+ */
resizeable: function() {
$.error( 'Browser does not support window.postMessage' );
}
@@ -122,7 +122,7 @@
// Some browsers send structured data, some send JSON strings
if ( 'object' === typeof event.data ) {
- data = event.data;
+ data = event.data.data;
} else {
try {
data = JSON.parse( event.data );
@@ -131,10 +131,13 @@
}
}
- if ( !data ) {
+ if ( !data.data ) {
return;
}
+ // Un-nest
+ data = data.data;
+
// Is it a resize event?
if ( 'undefined' === typeof data.action || 'resize' !== data.action ) {
return;
@@ -242,6 +245,10 @@
if ( 0 !== value ) {
target[variable]( value );
+ var container = target.parent();
+ if ( container.hasClass( 'slim-likes-widget' ) ) {
+ container[variable]( value );
+ }
}
} );
@@ -269,7 +276,7 @@
return methods.on.apply( this );
} else {
$.error( 'Method ' + method + ' does not exist on Jetpack.resizeable' );
- }
+ }
}
} );
})(jQuery);
diff --git a/plugins/jetpack/_inc/jquery.spin.js b/plugins/jetpack/_inc/jquery.spin.js
index 4642af13..1e901ca6 100644
--- a/plugins/jetpack/_inc/jquery.spin.js
+++ b/plugins/jetpack/_inc/jquery.spin.js
@@ -1,86 +1,104 @@
-/*
- * Matt Husby https://github.com/matthusby/spin.js
- * Based on the jquery plugin by Bradley Smith
- * https://gist.github.com/1290439
+/**
+ * Copyright (c) 2011-2013 Felix Gnass
+ * Licensed under the MIT license
*/
/*
-Add spin to the jQuery object
-If color is not passed the spinner will be black
-You can now create a spinner using any of the variants below:
-$("#el").spin(); // Produces default Spinner
-$("#el").spin("small"); // Produces a 'small' Spinner
-$("#el").spin("large", "white"); // Produces a 'large' Spinner in white (or any valid CSS color).
-$("#el").spin({ ... }); // Produces a Spinner using your custom settings.
-$("#el").spin("small-right"); // Pin the small spinner to the right edge
-$("#el").spin("{small, medium, large}-{left, right, top, bottom}"); // All options for where to pin
-$("#el").spin(false); // Kills the spinner.
+
+Basic Usage:
+============
+
+$('#el').spin(); // Creates a default Spinner using the text color of #el.
+$('#el').spin({ ... }); // Creates a Spinner using the provided options.
+
+$('#el').spin(false); // Stops and removes the spinner.
+
+Using Presets:
+==============
+
+$('#el').spin('small'); // Creates a 'small' Spinner using the text color of #el.
+$('#el').spin('large', '#fff'); // Creates a 'large' white Spinner.
+
+Adding a custom preset:
+=======================
+
+$.fn.spin.presets.flower = {
+ lines: 9
+ length: 10
+ width: 20
+ radius: 0
+}
+
+$('#el').spin('flower', 'red');
+
*/
-( function( $ ) {
- $.fn.spin = function( opts, color ) {
- var presets = {
- "small": { lines: 8, length: 2, width: 2, radius: 3, trail: 60, speed: 1.3 },
- "medium": { lines: 8, length: 4, width: 3, radius: 5, trail: 60, speed: 1.3 },
- "large": { lines: 10, length: 6, width: 4, radius: 7, trail: 60, speed: 1.3 }
- };
- if ( Spinner ) {
- return this.each( function() {
- var $this = $( this ),
- data = $this.data();
-
- if ( data.spinner ) {
- data.spinner.stop();
- delete data.spinner;
- }
- if ( opts !== false ) {
- var spinner_options;
- if ( typeof opts === "string" ) {
- var spinner_base = opts.indexOf( '-' );
- if( spinner_base == -1 ) {
- spinner_base = opts;
- } else {
- spinner_base = opts.substring( 0, spinner_base );
- }
- if ( spinner_base in presets ) {
- spinner_options = presets[spinner_base];
- } else {
- spinner_options = {};
- }
- var padding;
- if ( opts.indexOf( "-right" ) != -1 ) {
- padding = jQuery( this ).css( 'padding-left' );
- if( typeof padding === "undefined" ) {
- padding = 0;
- } else {
- padding = padding.replace( 'px', '' );
- }
- spinner_options.left = jQuery( this ).outerWidth() - ( 2 * ( spinner_options.length + spinner_options.width + spinner_options.radius ) ) - padding - 5;
- }
- if ( opts.indexOf( '-left' ) != -1 ) {
- spinner_options.left = 5;
- }
- if ( opts.indexOf( '-top' ) != -1 ) {
- spinner_options.top = 5;
- }
- if ( opts.indexOf( '-bottom' ) != -1 ) {
- padding = jQuery( this ).css( 'padding-top' );
- if( typeof padding === "undefined" ) {
- padding = 0;
- } else {
- padding = padding.replace( 'px', '' );
- }
- spinner_options.top = jQuery( this ).outerHeight() - ( 2 * ( spinner_options.length + spinner_options.width + spinner_options.radius ) ) - padding - 5;
- }
- }
- if( color ){
- spinner_options.color = color;
- }
- data.spinner = new Spinner( spinner_options ).spin( this );
- }
- });
- } else {
- throw "Spinner class not available.";
- }
- };
-})( jQuery ); \ No newline at end of file
+(function(factory) {
+
+ if (typeof exports == 'object') {
+ // CommonJS
+ factory(require('jquery'), require('spin'))
+ }
+ else if (typeof define == 'function' && define.amd) {
+ // AMD, register as anonymous module
+ define(['jquery', 'spin'], factory)
+ }
+ else {
+ // Browser globals
+ if (!window.Spinner) throw new Error('Spin.js not present')
+ factory(window.jQuery, window.Spinner)
+ }
+
+}(function($, Spinner) {
+
+ $.fn.spin = function(opts, color) {
+
+ return this.each(function() {
+ var $this = $(this),
+ data = $this.data();
+
+ if (data.spinner) {
+ data.spinner.stop();
+ delete data.spinner;
+ }
+ if (opts !== false) {
+ opts = $.extend(
+ { color: color || $this.css('color') },
+ $.fn.spin.presets[opts] || opts
+ )
+ // Begin WordPress Additions
+ // To use opts.right, you need to have specified a length, width, and radius.
+ if ( typeof opts.right !== 'undefined' && typeof opts.length !== 'undefined'
+ && typeof opts.width !== 'undefined' && typeof opts.radius !== 'undefined' ) {
+ var pad = $this.css( 'padding-left' );
+ pad = ( typeof pad === 'undefined' ) ? 0 : parseInt( pad, 10 );
+ opts.left = $this.outerWidth() - ( 2 * ( opts.length + opts.width + opts.radius ) ) - pad - opts.right;
+ delete opts.right;
+ }
+ // End WordPress Additions
+ data.spinner = new Spinner(opts).spin(this)
+ }
+ })
+ }
+
+ $.fn.spin.presets = {
+ tiny: { lines: 8, length: 2, width: 2, radius: 3 },
+ small: { lines: 8, length: 4, width: 3, radius: 5 },
+ large: { lines: 10, length: 8, width: 4, radius: 8 }
+ }
+
+}));
+
+// Jetpack Presets Overrides:
+(function($){
+ $.fn.spin.presets.wp = { trail: 60, speed: 1.3 };
+ $.fn.spin.presets.small = $.extend( { lines: 8, length: 2, width: 2, radius: 3 }, $.fn.spin.presets.wp );
+ $.fn.spin.presets.medium = $.extend( { lines: 8, length: 4, width: 3, radius: 5 }, $.fn.spin.presets.wp );
+ $.fn.spin.presets.large = $.extend( { lines: 10, length: 6, width: 4, radius: 7 }, $.fn.spin.presets.wp );
+ $.fn.spin.presets['small-left'] = $.extend( { left: 5 }, $.fn.spin.presets.small );
+ $.fn.spin.presets['small-right'] = $.extend( { right: 5 }, $.fn.spin.presets.small );
+ $.fn.spin.presets['medium-left'] = $.extend( { left: 5 }, $.fn.spin.presets.medium );
+ $.fn.spin.presets['medium-right'] = $.extend( { right: 5 }, $.fn.spin.presets.medium );
+ $.fn.spin.presets['large-left'] = $.extend( { left: 5 }, $.fn.spin.presets.large );
+ $.fn.spin.presets['large-right'] = $.extend( { right: 5 }, $.fn.spin.presets.large );
+})(jQuery);
diff --git a/plugins/jetpack/_inc/postmessage.js b/plugins/jetpack/_inc/postmessage.js
index e8933bca..51f8567b 100644
--- a/plugins/jetpack/_inc/postmessage.js
+++ b/plugins/jetpack/_inc/postmessage.js
@@ -105,7 +105,7 @@ var NO_JQUERY = {};
bind: function(type, fn, origin, hash, async_reply) {
pm._replyBind ( type, fn, origin, hash, async_reply );
},
-
+
_replyBind: function(type, fn, origin, hash, isCallback) {
if (("postMessage" in window) && !hash) {
pm._bind();
@@ -243,7 +243,7 @@ var NO_JQUERY = {};
pm.send({target:e.source, data:data, type:msg.callback});
}
}
-
+
try {
if ( o.callback ) {
o.fn(msg.data, sendReply, e);
@@ -390,7 +390,7 @@ var NO_JQUERY = {};
pm.send({target:source_window, data:data, type:msg.callback, hash:true, url:hash.source.url});
}
}
-
+
try {
if ( o.callback ) {
o.fn(msg.data, sendReply);
diff --git a/plugins/jetpack/_inc/spin.js b/plugins/jetpack/_inc/spin.js
index f506cd2b..c66c607a 100644
--- a/plugins/jetpack/_inc/spin.js
+++ b/plugins/jetpack/_inc/spin.js
@@ -1,301 +1,349 @@
-//fgnass.github.com/spin.js#v1.2.4
-(function(window, document, undefined) {
+//fgnass.github.com/spin.js#v1.3
/**
- * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
+ * Copyright (c) 2011-2013 Felix Gnass
* Licensed under the MIT license
*/
-
- var prefixes = ['webkit', 'Moz', 'ms', 'O']; /* Vendor prefixes */
- var animations = {}; /* Animation rules keyed by their name */
- var useCssAnimations;
-
- /**
- * Utility function to create elements. If no tag name is given,
- * a DIV is created. Optionally properties can be passed.
- */
- function createEl(tag, prop) {
- var el = document.createElement(tag || 'div');
- var n;
-
- for(n in prop) {
- el[n] = prop[n];
- }
- return el;
- }
-
- /**
- * Appends children and returns the parent.
- */
- function ins(parent /* child1, child2, ...*/) {
- for (var i=1, n=arguments.length; i<n; i++) {
- parent.appendChild(arguments[i]);
- }
- return parent;
- }
-
- /**
- * Insert a new stylesheet to hold the @keyframe or VML rules.
- */
- var sheet = function() {
- var el = createEl('style');
- ins(document.getElementsByTagName('head')[0], el);
- return el.sheet || el.styleSheet;
- }();
-
- /**
- * Creates an opacity keyframe animation rule and returns its name.
- * Since most mobile Webkits have timing issues with animation-delay,
- * we create separate rules for each line/segment.
- */
- function addAnimation(alpha, trail, i, lines) {
- var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-');
- var start = 0.01 + i/lines*100;
- var z = Math.max(1-(1-alpha)/trail*(100-start) , alpha);
- var prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase();
- var pre = prefix && '-'+prefix+'-' || '';
-
- if (!animations[name]) {
- sheet.insertRule(
- '@' + pre + 'keyframes ' + name + '{' +
- '0%{opacity:'+z+'}' +
- start + '%{opacity:'+ alpha + '}' +
- (start+0.01) + '%{opacity:1}' +
- (start+trail)%100 + '%{opacity:'+ alpha + '}' +
- '100%{opacity:'+ z + '}' +
- '}', 0);
- animations[name] = 1;
- }
- return name;
- }
-
- /**
- * Tries various vendor prefixes and returns the first supported property.
- **/
- function vendor(el, prop) {
- var s = el.style;
- var pp;
- var i;
-
- if(s[prop] !== undefined) return prop;
- prop = prop.charAt(0).toUpperCase() + prop.slice(1);
- for(i=0; i<prefixes.length; i++) {
- pp = prefixes[i]+prop;
- if(s[pp] !== undefined) return pp;
- }
- }
-
- /**
- * Sets multiple style properties at once.
- */
- function css(el, prop) {
- for (var n in prop) {
- el.style[vendor(el, n)||n] = prop[n];
- }
- return el;
- }
-
- /**
- * Fills in default values.
- */
- function merge(obj) {
- for (var i=1; i < arguments.length; i++) {
- var def = arguments[i];
- for (var n in def) {
- if (obj[n] === undefined) obj[n] = def[n];
- }
- }
- return obj;
- }
-
- /**
- * Returns the absolute page-offset of the given element.
- */
- function pos(el) {
- var o = {x:el.offsetLeft, y:el.offsetTop};
- while((el = el.offsetParent)) {
- o.x+=el.offsetLeft;
- o.y+=el.offsetTop;
- }
- return o;
- }
-
- var defaults = {
- lines: 12, // The number of lines to draw
- length: 7, // The length of each line
- width: 5, // The line thickness
- radius: 10, // The radius of the inner circle
- color: '#000', // #rgb or #rrggbb
- speed: 1, // Rounds per second
- trail: 100, // Afterglow percentage
- opacity: 1/4, // Opacity of the lines
- fps: 20, // Frames per second when using setTimeout()
- zIndex: 2e9, // Use a high z-index by default
- className: 'spinner', // CSS class to assign to the element
- top: 'auto', // center vertically
- left: 'auto' // center horizontally
- };
-
- /** The constructor */
- var Spinner = function Spinner(o) {
- if (!this.spin) return new Spinner(o);
- this.opts = merge(o || {}, Spinner.defaults, defaults);
- };
-
- Spinner.defaults = {};
- Spinner.prototype = {
- spin: function(target) {
- this.stop();
- var self = this;
- var o = self.opts;
- var el = self.el = css(createEl(0, {className: o.className}), {position: 'relative', zIndex: o.zIndex});
- var mid = o.radius+o.length+o.width;
- var ep; // element position
- var tp; // target position
-
- if (target) {
- target.insertBefore(el, target.firstChild||null);
- tp = pos(target);
- ep = pos(el);
- css(el, {
- left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : o.left+mid) + 'px',
- top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : o.top+mid) + 'px'
- });
- }
-
- el.setAttribute('aria-role', 'progressbar');
- self.lines(el, self.opts);
-
- if (!useCssAnimations) {
- // No CSS animation support, use setTimeout() instead
- var i = 0;
- var fps = o.fps;
- var f = fps/o.speed;
- var ostep = (1-o.opacity)/(f*o.trail / 100);
- var astep = f/o.lines;
-
- !function anim() {
- i++;
- for (var s=o.lines; s; s--) {
- var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
- self.opacity(el, o.lines-s, alpha, o);
- }
- self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
- }();
- }
- return self;
- },
- stop: function() {
- var el = this.el;
- if (el) {
- clearTimeout(this.timeout);
- if (el.parentNode) el.parentNode.removeChild(el);
- this.el = undefined;
- }
- return this;
- },
- lines: function(el, o) {
- var i = 0;
- var seg;
-
- function fill(color, shadow) {
- return css(createEl(), {
- position: 'absolute',
- width: (o.length+o.width) + 'px',
- height: o.width + 'px',
- background: color,
- boxShadow: shadow,
- transformOrigin: 'left',
- transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
- borderRadius: (o.width>>1) + 'px'
- });
- }
- for (; i < o.lines; i++) {
- seg = css(createEl(), {
- position: 'absolute',
- top: 1+~(o.width/2) + 'px',
- transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
- opacity: o.opacity,
- animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
- });
- if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
- ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
- }
- return el;
- },
- opacity: function(el, i, val) {
- if (i < el.childNodes.length) el.childNodes[i].style.opacity = val;
- }
- };
-
- /////////////////////////////////////////////////////////////////////////
- // VML rendering for IE
- /////////////////////////////////////////////////////////////////////////
-
- /**
- * Check and init VML support
- */
- !function() {
- var s = css(createEl('group'), {behavior: 'url(#default#VML)'});
- var i;
-
- if (!vendor(s, 'transform') && s.adj) {
-
- // VML support detected. Insert CSS rules ...
- for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');
-
- Spinner.prototype.lines = function(el, o) {
- var r = o.length+o.width;
- var s = 2*r;
-
- function grp() {
- return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
- }
-
- var margin = -(o.width+o.length)*2+'px';
- var g = css(grp(), {position: 'absolute', top: margin, left: margin});
-
- var i;
-
- function seg(i, dx, filter) {
- ins(g,
- ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
- ins(css(createEl('roundrect', {arcsize: 1}), {
- width: r,
- height: o.width,
- left: o.radius,
- top: -o.width>>1,
- filter: filter
- }),
- createEl('fill', {color: o.color, opacity: o.opacity}),
- createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
- )
- )
- );
- }
-
- if (o.shadow) {
- for (i = 1; i <= o.lines; i++) {
- seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
- }
- }
- for (i = 1; i <= o.lines; i++) seg(i);
- return ins(el, g);
- };
- Spinner.prototype.opacity = function(el, i, val, o) {
- var c = el.firstChild;
- o = o.shadow && o.lines || 0;
- if (c && i+o < c.childNodes.length) {
- c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild;
- if (c) c.opacity = val;
- }
- };
- }
- else {
- useCssAnimations = vendor(s, 'animation');
- }
- }();
-
- window.Spinner = Spinner;
-
-})(window, document); \ No newline at end of file
+(function(root, factory) {
+
+ /* CommonJS */
+ if (typeof exports == 'object') module.exports = factory()
+
+ /* AMD module */
+ else if (typeof define == 'function' && define.amd) define(factory)
+
+ /* Browser global */
+ else root.Spinner = factory()
+}
+(this, function() {
+ "use strict";
+
+ var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
+ , animations = {} /* Animation rules keyed by their name */
+ , useCssAnimations /* Whether to use CSS animations or setTimeout */
+
+ /**
+ * Utility function to create elements. If no tag name is given,
+ * a DIV is created. Optionally properties can be passed.
+ */
+ function createEl(tag, prop) {
+ var el = document.createElement(tag || 'div')
+ , n
+
+ for(n in prop) el[n] = prop[n]
+ return el
+ }
+
+ /**
+ * Appends children and returns the parent.
+ */
+ function ins(parent /* child1, child2, ...*/) {
+ for (var i=1, n=arguments.length; i<n; i++)
+ parent.appendChild(arguments[i])
+
+ return parent
+ }
+
+ /**
+ * Insert a new stylesheet to hold the @keyframe or VML rules.
+ */
+ var sheet = (function() {
+ var el = createEl('style', {type : 'text/css'})
+ ins(document.getElementsByTagName('head')[0], el)
+ return el.sheet || el.styleSheet
+ }())
+
+ /**
+ * Creates an opacity keyframe animation rule and returns its name.
+ * Since most mobile Webkits have timing issues with animation-delay,
+ * we create separate rules for each line/segment.
+ */
+ function addAnimation(alpha, trail, i, lines) {
+ var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-')
+ , start = 0.01 + i/lines * 100
+ , z = Math.max(1 - (1-alpha) / trail * (100-start), alpha)
+ , prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase()
+ , pre = prefix && '-' + prefix + '-' || ''
+
+ if (!animations[name]) {
+ sheet.insertRule(
+ '@' + pre + 'keyframes ' + name + '{' +
+ '0%{opacity:' + z + '}' +
+ start + '%{opacity:' + alpha + '}' +
+ (start+0.01) + '%{opacity:1}' +
+ (start+trail) % 100 + '%{opacity:' + alpha + '}' +
+ '100%{opacity:' + z + '}' +
+ '}', sheet.cssRules.length)
+
+ animations[name] = 1
+ }
+
+ return name
+ }
+
+ /**
+ * Tries various vendor prefixes and returns the first supported property.
+ */
+ function vendor(el, prop) {
+ var s = el.style
+ , pp
+ , i
+
+ if(s[prop] !== undefined) return prop
+ prop = prop.charAt(0).toUpperCase() + prop.slice(1)
+ for(i=0; i<prefixes.length; i++) {
+ pp = prefixes[i]+prop
+ if(s[pp] !== undefined) return pp
+ }
+ }
+
+ /**
+ * Sets multiple style properties at once.
+ */
+ function css(el, prop) {
+ for (var n in prop)
+ el.style[vendor(el, n)||n] = prop[n]
+
+ return el
+ }
+
+ /**
+ * Fills in default values.
+ */
+ function merge(obj) {
+ for (var i=1; i < arguments.length; i++) {
+ var def = arguments[i]
+ for (var n in def)
+ if (obj[n] === undefined) obj[n] = def[n]
+ }
+ return obj
+ }
+
+ /**
+ * Returns the absolute page-offset of the given element.
+ */
+ function pos(el) {
+ var o = { x:el.offsetLeft, y:el.offsetTop }
+ while((el = el.offsetParent))
+ o.x+=el.offsetLeft, o.y+=el.offsetTop
+
+ return o
+ }
+
+ // Built-in defaults
+
+ var defaults = {
+ lines: 12, // The number of lines to draw
+ length: 7, // The length of each line
+ width: 5, // The line thickness
+ radius: 10, // The radius of the inner circle
+ rotate: 0, // Rotation offset
+ corners: 1, // Roundness (0..1)
+ color: '#000', // #rgb or #rrggbb
+ direction: 1, // 1: clockwise, -1: counterclockwise
+ speed: 1, // Rounds per second
+ trail: 100, // Afterglow percentage
+ opacity: 1/4, // Opacity of the lines
+ fps: 20, // Frames per second when using setTimeout()
+ zIndex: 2e9, // Use a high z-index by default
+ className: 'spinner', // CSS class to assign to the element
+ top: 'auto', // center vertically
+ left: 'auto', // center horizontally
+ position: 'relative' // element position
+ }
+
+ /** The constructor */
+ function Spinner(o) {
+ if (typeof this == 'undefined') return new Spinner(o)
+ this.opts = merge(o || {}, Spinner.defaults, defaults)
+ }
+
+ // Global defaults that override the built-ins:
+ Spinner.defaults = {}
+
+ merge(Spinner.prototype, {
+
+ /**
+ * Adds the spinner to the given target element. If this instance is already
+ * spinning, it is automatically removed from its previous target b calling
+ * stop() internally.
+ */
+ spin: function(target) {
+ this.stop()
+
+ var self = this
+ , o = self.opts
+ , el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex})
+ , mid = o.radius+o.length+o.width
+ , ep // element position
+ , tp // target position
+
+ if (target) {
+ target.insertBefore(el, target.firstChild||null)
+ tp = pos(target)
+ ep = pos(el)
+ css(el, {
+ left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : parseInt(o.left, 10) + mid) + 'px',
+ top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px'
+ })
+ }
+
+ el.setAttribute('role', 'progressbar')
+ self.lines(el, self.opts)
+
+ if (!useCssAnimations) {
+ // No CSS animation support, use setTimeout() instead
+ var i = 0
+ , start = (o.lines - 1) * (1 - o.direction) / 2
+ , alpha
+ , fps = o.fps
+ , f = fps/o.speed
+ , ostep = (1-o.opacity) / (f*o.trail / 100)
+ , astep = f/o.lines
+
+ ;(function anim() {
+ i++;
+ for (var j = 0; j < o.lines; j++) {
+ alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)
+
+ self.opacity(el, j * o.direction + start, alpha, o)
+ }
+ self.timeout = self.el && setTimeout(anim, ~~(1000/fps))
+ })()
+ }
+ return self
+ },
+
+ /**
+ * Stops and removes the Spinner.
+ */
+ stop: function() {
+ var el = this.el
+ if (el) {
+ clearTimeout(this.timeout)
+ if (el.parentNode) el.parentNode.removeChild(el)
+ this.el = undefined
+ }
+ return this
+ },
+
+ /**
+ * Internal method that draws the individual lines. Will be overwritten
+ * in VML fallback mode below.
+ */
+ lines: function(el, o) {
+ var i = 0
+ , start = (o.lines - 1) * (1 - o.direction) / 2
+ , seg
+
+ function fill(color, shadow) {
+ return css(createEl(), {
+ position: 'absolute',
+ width: (o.length+o.width) + 'px',
+ height: o.width + 'px',
+ background: color,
+ boxShadow: shadow,
+ transformOrigin: 'left',
+ transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
+ borderRadius: (o.corners * o.width>>1) + 'px'
+ })
+ }
+
+ for (; i < o.lines; i++) {
+ seg = css(createEl(), {
+ position: 'absolute',
+ top: 1+~(o.width/2) + 'px',
+ transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
+ opacity: o.opacity,
+ animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite'
+ })
+
+ if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}))
+
+ ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')))
+ }
+ return el
+ },
+
+ /**
+ * Internal method that adjusts the opacity of a single line.
+ * Will be overwritten in VML fallback mode below.
+ */
+ opacity: function(el, i, val) {
+ if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
+ }
+
+ })
+
+
+ function initVML() {
+
+ /* Utility function to create a VML tag */
+ function vml(tag, attr) {
+ return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
+ }
+
+ // No CSS transforms but VML support, add a CSS rule for VML elements:
+ sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')
+
+ Spinner.prototype.lines = function(el, o) {
+ var r = o.length+o.width
+ , s = 2*r
+
+ function grp() {
+ return css(
+ vml('group', {
+ coordsize: s + ' ' + s,
+ coordorigin: -r + ' ' + -r
+ }),
+ { width: s, height: s }
+ )
+ }
+
+ var margin = -(o.width+o.length)*2 + 'px'
+ , g = css(grp(), {position: 'absolute', top: margin, left: margin})
+ , i
+
+ function seg(i, dx, filter) {
+ ins(g,
+ ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
+ ins(css(vml('roundrect', {arcsize: o.corners}), {
+ width: r,
+ height: o.width,
+ left: o.radius,
+ top: -o.width>>1,
+ filter: filter
+ }),
+ vml('fill', {color: o.color, opacity: o.opacity}),
+ vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
+ )
+ )
+ )
+ }
+
+ if (o.shadow)
+ for (i = 1; i <= o.lines; i++)
+ seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')
+
+ for (i = 1; i <= o.lines; i++) seg(i)
+ return ins(el, g)
+ }
+
+ Spinner.prototype.opacity = function(el, i, val, o) {
+ var c = el.firstChild
+ o = o.shadow && o.lines || 0
+ if (c && i+o < c.childNodes.length) {
+ c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild
+ if (c) c.opacity = val
+ }
+ }
+ }
+
+ var probe = css(createEl('group'), {behavior: 'url(#default#VML)'})
+
+ if (!vendor(probe, 'transform') && probe.adj) initVML()
+ else useCssAnimations = vendor(probe, 'animation')
+
+ return Spinner
+
+}));
diff --git a/plugins/jetpack/class.jetpack-ixr-client.php b/plugins/jetpack/class.jetpack-ixr-client.php
index 8d6e52fe..7eefee5f 100644
--- a/plugins/jetpack/class.jetpack-ixr-client.php
+++ b/plugins/jetpack/class.jetpack-ixr-client.php
@@ -49,7 +49,7 @@ class Jetpack_IXR_Client extends IXR_Client {
$this->error = new IXR_Error( -32300, 'transport error - HTTP status code was not 200' );
return false;
}
-
+
$content = wp_remote_retrieve_body( $response );
// Now parse what we've got back
diff --git a/plugins/jetpack/class.jetpack-post-images.php b/plugins/jetpack/class.jetpack-post-images.php
index afdcacfa..5829fcc6 100644
--- a/plugins/jetpack/class.jetpack-post-images.php
+++ b/plugins/jetpack/class.jetpack-post-images.php
@@ -15,15 +15,17 @@ class Jetpack_PostImages {
* If a slideshow is embedded within a post, then parse out the images involved and return them
*/
static function from_slideshow( $post_id, $width = 200, $height = 200 ) {
+ $images = array();
+
$post = get_post( $post_id );
+ if ( !empty( $post->post_password ) )
+ return $images;
if ( false === strpos( $post->post_content, '[slideshow' ) )
return false; // no slideshow - bail
$permalink = get_permalink( $post->ID );
- $images = array();
-
// Mechanic: Somebody set us up the bomb
$old_post = $GLOBALS['post'];
$GLOBALS['post'] = $post;
@@ -79,15 +81,17 @@ class Jetpack_PostImages {
* If a gallery is detected, then get all the images from it.
*/
static function from_gallery( $post_id ) {
+ $images = array();
+
$post = get_post( $post_id );
+ if ( !empty( $post->post_password ) )
+ return $images;
if ( false === strpos( $post->post_content, '[gallery' ) )
return false; // no gallery - bail
$permalink = get_permalink( $post->ID );
- $images = array();
-
// CATS: All your base are belong to us
$old_post = $GLOBALS['post'];
$GLOBALS['post'] = $post;
@@ -145,6 +149,11 @@ class Jetpack_PostImages {
* their dimensions are at or above a required minimum.
*/
static function from_attachment( $post_id, $width = 200, $height = 200 ) {
+ $images = array();
+
+ $post = get_post( $post_id );
+ if ( !empty( $post->post_password ) )
+ return $images;
$post_images = get_posts( array(
'post_parent' => $post_id, // Must be children of post
@@ -158,8 +167,6 @@ class Jetpack_PostImages {
$permalink = get_permalink( $post_id );
- $images = array();
-
foreach ( $post_images as $post_image ) {
$meta = wp_get_attachment_metadata( $post_image->ID );
// Must be larger than 200x200
@@ -210,9 +217,12 @@ class Jetpack_PostImages {
static function from_thumbnail( $post_id, $width = 200, $height = 200 ) {
$images = array();
- if ( !function_exists( 'get_post_thumbnail_id' ) ) {
+ $post = get_post( $post_id );
+ if ( !empty( $post->post_password ) )
+ return $images;
+
+ if ( !function_exists( 'get_post_thumbnail_id' ) )
return $images;
- }
$thumb = get_post_thumbnail_id( $post_id );
@@ -251,10 +261,12 @@ class Jetpack_PostImages {
if ( is_numeric( $html_or_id ) ) {
$post = get_post( $html_or_id );
-
- if ( !$post )
+ if ( empty( $post ) || !empty( $post->post_password ) )
return $images;
+
$html = $post->post_content; // DO NOT apply the_content filters here, it will cause loops
+ } else {
+ $html = $html_or_id;
}
if ( !$html )
diff --git a/plugins/jetpack/class.jetpack-signature.php b/plugins/jetpack/class.jetpack-signature.php
index 975375ab..3f6c16fb 100644
--- a/plugins/jetpack/class.jetpack-signature.php
+++ b/plugins/jetpack/class.jetpack-signature.php
@@ -56,7 +56,7 @@ class Jetpack_Signature {
}
}
- $method = isset( $override['method'] ) ? $override['method'] : $_SERVER['REQUEST_METHOD'];
+ $method = isset( $override['method'] ) ? $override['method'] : $_SERVER['REQUEST_METHOD'];
return $this->sign_request( $a['token'], $a['timestamp'], $a['nonce'], $a['body-hash'], $method, $url, $body, true );
}
@@ -99,7 +99,7 @@ class Jetpack_Signature {
return new Jetpack_Error( 'invalid_body_hash', 'The body hash does not match.' );
}
} else {
- if ( $verify_body_hash && jetpack_sha1_base64( $body ) != $body_hash ) {
+ if ( $verify_body_hash && jetpack_sha1_base64( $body ) !== $body_hash ) {
return new Jetpack_Error( 'invalid_body_hash', 'The body hash does not match.' );
}
}
diff --git a/plugins/jetpack/class.jetpack-user-agent.php b/plugins/jetpack/class.jetpack-user-agent.php
index 3ae1bb85..4c63a65a 100644
--- a/plugins/jetpack/class.jetpack-user-agent.php
+++ b/plugins/jetpack/class.jetpack-user-agent.php
@@ -78,6 +78,7 @@ class Jetpack_User_Agent_Info {
const PLATFORM_J2ME_MIDP = 'j2me_midp';
const PLATFORM_ANDROID = 'android';
const PLATFORM_ANDROID_TABLET = 'android_tablet';
+ const PLATFORM_FIREFOX_OS = 'firefoxOS';
var $dumb_agents = array(
'nokia', 'blackberry', 'philips', 'samsung', 'sanyo', 'sony', 'panasonic', 'webos',
@@ -139,6 +140,8 @@ class Jetpack_User_Agent_Info {
return 'webos';
elseif ( $this->is_S60_OSSBrowser() )
return 'series60';
+ elseif ( $this->is_firefox_os() )
+ return 'firefoxOS';
elseif ( $this->is_firefox_mobile() )
return 'firefox_mobile';
elseif ( $this->is_MaemoTablet() )
@@ -228,6 +231,9 @@ class Jetpack_User_Agent_Info {
elseif ( $this->is_J2ME_platform() ) {
$this->_platform = self::PLATFORM_J2ME_MIDP;
}
+ elseif ( $this->is_firefox_os() ) {
+ $this->_platform = self::PLATFORM_FIREFOX_OS;
+ }
else
$this->_platform = false;
@@ -297,6 +303,12 @@ class Jetpack_User_Agent_Info {
$this->isTierRichCss = false;
$this->isTierGenericMobile = false;
}
+ elseif ( $this->is_firefox_os() ) {
+ $this->matched_agent = 'firefoxOS';
+ $this->isTierIphone = true;
+ $this->isTierRichCss = false;
+ $this->isTierGenericMobile = false;
+ }
elseif ( $this->is_firefox_mobile() ) {
$this->matched_agent = 'fennec';
$this->isTierIphone = true;
@@ -377,7 +389,7 @@ class Jetpack_User_Agent_Info {
// Detects if the user is using a tablet.
// props Corey Gilmore, BGR.com
- function is_tablet() {
+ static function is_tablet() {
return ( 0 // never true, but makes it easier to manage our list of tablet conditions
|| self::is_ipad()
|| self::is_android_tablet()
@@ -387,14 +399,14 @@ class Jetpack_User_Agent_Info {
|| self::is_TouchPad()
);
}
-
+
/*
* Detects if the current UA is the default iPhone or iPod Touch Browser.
*
* DEPRECATED: use is_iphone_or_ipod
*
*/
- function is_iphoneOrIpod(){
+ static function is_iphoneOrIpod(){
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -421,7 +433,7 @@ class Jetpack_User_Agent_Info {
* Otherwise those browsers will be 'catched' by the iphone string.
*
*/
- function is_iphone_or_ipod( $type = 'iphone-any' ) {
+ static function is_iphone_or_ipod( $type = 'iphone-any' ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -438,61 +450,61 @@ class Jetpack_User_Agent_Info {
return $is_iphone;
}
-
+
/*
* Detects if the current UA is Chrome for iOS
*
* The User-Agent string in Chrome for iOS is the same as the Mobile Safari User-Agent, with CriOS/<ChromeRevision> instead of Version/<VersionNum>.
* - Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3
*/
- function is_chrome_for_iOS( ) {
+ static function is_chrome_for_iOS( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
-
+
if ( self::is_iphone_or_ipod( 'iphone-safari' ) === false ) return false;
-
+
$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
-
+
if ( strpos( $ua, 'crios/' ) !== false )
return true;
else
return false;
}
-
-
+
+
/*
* Detects if the current UA is Twitter for iPhone
- *
+ *
* Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_5 like Mac OS X; nb-no) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8L1 Twitter for iPhone
* Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 Twitter for iPhone
- *
+ *
*/
- function is_twitter_for_iphone( ) {
+ static function is_twitter_for_iphone( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
-
+
$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
if ( strpos( $ua, 'ipad' ) !== false )
return false;
-
+
if ( strpos( $ua, 'twitter for iphone' ) !== false )
return true;
else
return false;
}
-
+
/*
* Detects if the current UA is Twitter for iPad
- *
+ *
* Old version 4.X - Mozilla/5.0 (iPad; U; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8L1 Twitter for iPad
* Ver 5.0 or Higher - Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 Twitter for iPhone
- *
+ *
*/
- function is_twitter_for_ipad( ) {
+ static function is_twitter_for_ipad( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
-
+
$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
if ( strpos( $ua, 'twitter for ipad' ) !== false )
@@ -502,7 +514,7 @@ class Jetpack_User_Agent_Info {
else
return false;
}
-
+
/*
* Detects if the current UA is Facebook for iPhone
@@ -510,7 +522,7 @@ class Jetpack_User_Agent_Info {
* - Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_0 like Mac OS X; en_US) AppleWebKit (KHTML, like Gecko) Mobile [FBAN/FBForIPhone;FBAV/4.0.2;FBBV/4020.0;FBDV/iPhone3,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/5.0;FBSS/2; FBCR/O2;FBID/phone;FBLC/en_US;FBSF/2.0]
* - Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 [FBAN/FBIOS;FBAV/5.0;FBBV/47423;FBDV/iPhone3,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/5.1.1;FBSS/2; FBCR/3ITA;FBID/phone;FBLC/en_US]
*/
- function is_facebook_for_iphone( ) {
+ static function is_facebook_for_iphone( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -535,7 +547,7 @@ class Jetpack_User_Agent_Info {
* - Mozilla/5.0 (iPad; U; CPU iPhone OS 5_0 like Mac OS X; en_US) AppleWebKit (KHTML, like Gecko) Mobile [FBAN/FBForIPhone;FBAV/4.0.2;FBBV/4020.0;FBDV/iPad2,1;FBMD/iPad;FBSN/iPhone OS;FBSV/5.0;FBSS/1; FBCR/;FBID/tablet;FBLC/en_US;FBSF/1.0]
* - Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10A403 [FBAN/FBIOS;FBAV/5.0;FBBV/47423;FBDV/iPad2,1;FBMD/iPad;FBSN/iPhone OS;FBSV/6.0;FBSS/1; FBCR/;FBID/tablet;FBLC/en_US]
*/
- function is_facebook_for_ipad( ) {
+ static function is_facebook_for_ipad( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -553,7 +565,7 @@ class Jetpack_User_Agent_Info {
/*
* Detects if the current UA is WordPress for iOS
*/
- function is_wordpress_for_ios( ) {
+ static function is_wordpress_for_ios( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -573,7 +585,7 @@ class Jetpack_User_Agent_Info {
* Otherwise those browsers will be 'catched' by the ipad string.
*
*/
- function is_ipad( $type = 'ipad-any' ) {
+ static function is_ipad( $type = 'ipad-any' ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -598,7 +610,7 @@ class Jetpack_User_Agent_Info {
* Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.1.1) Gecko/20110415 Firefox/4.0.2pre Fennec/4.0.1
* Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b2pre) Gecko/20081015 Fennec/1.0a1
*/
- function is_firefox_mobile( ) {
+ static function is_firefox_mobile( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -613,6 +625,26 @@ class Jetpack_User_Agent_Info {
/*
+ * Detects if the current browser is FirefoxOS Native browser
+ *
+ * Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
+ *
+ */
+ static function is_firefox_os( ) {
+
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
+ return false;
+
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
+
+ if ( strpos( $ua, 'mozilla' ) !== false && strpos( $ua, 'mobile' ) !== false && strpos( $ua, 'gecko' ) !== false && strpos( $ua, 'firefox' ) !== false)
+ return true;
+ else
+ return false;
+ }
+
+
+ /*
* Detects if the current browser is Opera Mobile
*
* What is the difference between Opera Mobile and Opera Mini?
@@ -623,7 +655,7 @@ class Jetpack_User_Agent_Info {
*
* Opera/9.80 (Windows NT 6.1; Opera Mobi/14316; U; en) Presto/2.7.81 Version/11.00"
*/
- function is_opera_mobile( ) {
+ static function is_opera_mobile( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -649,7 +681,7 @@ class Jetpack_User_Agent_Info {
* Opera/9.80 (BlackBerry; Opera Mini/5.1.22303/22.387; U; en) Presto/2.5.25 Version/10.54
*
*/
- function is_opera_mini( ) {
+ static function is_opera_mini( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -666,7 +698,7 @@ class Jetpack_User_Agent_Info {
* Detects if the current browser is Opera Mini, but not on a smart device OS(Android, iOS, etc)
* Used to send users on dumb devices to m.wor
*/
- function is_opera_mini_dumb( ) {
+ static function is_opera_mini_dumb( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -690,7 +722,7 @@ class Jetpack_User_Agent_Info {
* Opera Mini 5 Beta: Opera/9.80 (J2ME/MIDP; Opera Mini/5.0.15650/756; U; en) Presto/2.2.0
* Opera Mini 8: Opera/8.01 (J2ME/MIDP; Opera Mini/3.0.6306/1528; en; U; ssr)
*/
- function is_OperaMobile() {
+ static function is_OperaMobile() {
_deprecated_function( __FUNCTION__, 'always', 'is_opera_mini() or is_opera_mobile()' );
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
@@ -712,7 +744,7 @@ class Jetpack_User_Agent_Info {
* Detects if the current browser is a Windows Phone 7 device.
* ex: Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; LG; GW910)
*/
- function is_WindowsPhone7() {
+ static function is_WindowsPhone7() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -732,10 +764,10 @@ class Jetpack_User_Agent_Info {
* Detects if the current browser is a Windows Phone 8 device.
* ex: Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; ARM; Touch; IEMobile/10.0; <Manufacturer>; <Device> [;<Operator>])
*/
- function is_windows_phone_8() {
+ static function is_windows_phone_8() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
-
+
$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
if ( strpos( $ua, 'windows phone 8' ) === false ) {
return false;
@@ -743,8 +775,8 @@ class Jetpack_User_Agent_Info {
return true;
}
}
-
-
+
+
/*
* Detects if the current browser is on a Palm device running the new WebOS. This EXCLUDES TouchPad.
*
@@ -752,7 +784,7 @@ class Jetpack_User_Agent_Info {
* ex2: Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pixi/1.1
*
*/
- function is_PalmWebOS() {
+ static function is_PalmWebOS() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -775,7 +807,7 @@ class Jetpack_User_Agent_Info {
* TouchPad: Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 TouchPad/1.0
*
*/
- function is_TouchPad() {
+ static function is_TouchPad() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -801,7 +833,7 @@ class Jetpack_User_Agent_Info {
* Browser 7.1 (Nokia N97 (v12.0.024)) : Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/12.0.024; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.12344
*
*/
- function is_S60_OSSBrowser() {
+ static function is_S60_OSSBrowser() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -831,7 +863,7 @@ class Jetpack_User_Agent_Info {
* Detects if the device platform is the Symbian Series 60.
*
*/
- function is_symbian_platform() {
+ static function is_symbian_platform() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -864,7 +896,7 @@ class Jetpack_User_Agent_Info {
* This browser will report 'NokiaBrowser' in the header, however some older version will also report 'OviBrowser'.
*
*/
- function is_symbian_s40_platform() {
+ static function is_symbian_s40_platform() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -879,7 +911,7 @@ class Jetpack_User_Agent_Info {
return false;
}
- function is_J2ME_platform() {
+ static function is_J2ME_platform() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -899,7 +931,7 @@ class Jetpack_User_Agent_Info {
/*
* Detects if the current UA is on one of the Maemo-based Nokia Internet Tablets.
*/
- function is_MaemoTablet() {
+ static function is_MaemoTablet() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -922,7 +954,7 @@ class Jetpack_User_Agent_Info {
/*
* Detects if the current UA is a MeeGo device (Nokia Smartphone).
*/
- function is_MeeGo() {
+ static function is_MeeGo() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -943,7 +975,7 @@ class Jetpack_User_Agent_Info {
/*
is_webkit() can be used to check the User Agent for an webkit generic browser
*/
- function is_webkit() {
+ static function is_webkit() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -962,7 +994,7 @@ class Jetpack_User_Agent_Info {
* Detects if the current browser is the Native Android browser.
* @return boolean true if the browser is Android otherwise false
*/
- function is_android() {
+ static function is_android() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -985,7 +1017,7 @@ class Jetpack_User_Agent_Info {
*
* @return boolean true if the browser is Android and not 'mobile' otherwise false
*/
- function is_android_tablet( ) {
+ static function is_android_tablet( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -1012,7 +1044,7 @@ class Jetpack_User_Agent_Info {
*
* @return boolean true if the browser is Kindle Fire Native browser otherwise false
*/
- function is_kindle_fire( ) {
+ static function is_kindle_fire( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -1033,7 +1065,7 @@ class Jetpack_User_Agent_Info {
*
* @return boolean true if the browser is Kindle monochrome Native browser otherwise false
*/
- function is_kindle_touch( ) {
+ static function is_kindle_touch( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
@@ -1046,7 +1078,7 @@ class Jetpack_User_Agent_Info {
// Detect if user agent is the WordPress.com Windows 8 app (used ONLY on the custom oauth stylesheet)
- function is_windows8_auth( ) {
+ static function is_windows8_auth( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -1059,10 +1091,10 @@ class Jetpack_User_Agent_Info {
}
// Detect if user agent is the WordPress.com Windows 8 app.
- function is_wordpress_for_win8( ) {
+ static function is_wordpress_for_win8( ) {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
-
+
$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
$pos = strpos( $agent, 'wp-windows8' );
if ( $pos !== false )
@@ -1070,15 +1102,15 @@ class Jetpack_User_Agent_Info {
else
return false;
}
-
-
+
+
/*
* is_blackberry_tablet() can be used to check the User Agent for a RIM blackberry tablet
* The user agent of the BlackBerry® Tablet OS follows a format similar to the following:
* Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/0.0.1 Safari/534.8+
*
*/
- function is_blackberry_tablet() {
+ static function is_blackberry_tablet() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -1099,13 +1131,13 @@ class Jetpack_User_Agent_Info {
is_blackbeberry() can be used to check the User Agent for a blackberry device
Note that opera mini on BB matches this rule.
*/
- function is_blackbeberry() {
+ static function is_blackbeberry() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
-
+
$pos_blackberry = strpos( $agent, 'blackberry' );
if ( $pos_blackberry !== false ) {
if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
@@ -1120,7 +1152,7 @@ class Jetpack_User_Agent_Info {
/*
is_blackberry_10() can be used to check the User Agent for a BlackBerry 10 device.
*/
- function is_blackberry_10() {
+ static function is_blackberry_10() {
$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
return ( strpos( $agent, 'bb10' ) !== false ) && ( strpos( $agent, 'mobile' ) !== false );
}
@@ -1141,14 +1173,14 @@ class Jetpack_User_Agent_Info {
* @return string Version of the BB OS.
* If version is not found, get_blackbeberry_OS_version will return boolean false.
*/
- function get_blackbeberry_OS_version() {
+ static function get_blackbeberry_OS_version() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
if ( self::is_blackberry_10() )
return 'blackberry-10';
-
+
$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
$pos_blackberry = stripos( $agent, 'blackberry' );
@@ -1223,7 +1255,7 @@ class Jetpack_User_Agent_Info {
* @return string Type of the BB browser.
* If browser's version is not found, detect_blackbeberry_browser_version will return boolean false.
*/
- function detect_blackberry_browser_version() {
+ static function detect_blackberry_browser_version() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
@@ -1232,7 +1264,7 @@ class Jetpack_User_Agent_Info {
if ( self::is_blackberry_10() )
return 'blackberry-10';
-
+
$pos_blackberry = strpos( $agent, 'blackberry' );
if ( $pos_blackberry === false ) {
//not a blackberry device
@@ -1270,7 +1302,7 @@ class Jetpack_User_Agent_Info {
}
//Checks if a visitor is coming from one of the WordPress mobile apps
- function is_mobile_app() {
+ static function is_mobile_app() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
return false;
diff --git a/plugins/jetpack/class.jetpack-xmlrpc-server.php b/plugins/jetpack/class.jetpack-xmlrpc-server.php
index 3aa5adb1..fd1b8939 100644
--- a/plugins/jetpack/class.jetpack-xmlrpc-server.php
+++ b/plugins/jetpack/class.jetpack-xmlrpc-server.php
@@ -30,7 +30,7 @@ class Jetpack_XMLRPC_Server {
'jetpack.featuresEnabled' => array( $this, 'features_enabled' ),
'jetpack.getPost' => array( $this, 'get_post' ),
'jetpack.getPosts' => array( $this, 'get_posts' ),
- 'jetpack.getComment' => array( $this, 'get_comment' ),
+ 'jetpack.getComment' => array( $this, 'get_comment' ),
'jetpack.getComments' => array( $this, 'get_comments' ),
) );
@@ -158,7 +158,7 @@ class Jetpack_XMLRPC_Server {
function test_connection() {
return JETPACK__VERSION;
}
-
+
function test_api_user_code( $args ) {
$client_id = (int) $args[0];
$user_id = (int) $args[1];
@@ -279,7 +279,7 @@ class Jetpack_XMLRPC_Server {
return $sync_data;
}
-
+
function update_attachment_parent( $args ) {
$attachment_id = (int) $args[0];
$parent_id = (int) $args[1];
diff --git a/plugins/jetpack/class.json-api-endpoints.php b/plugins/jetpack/class.json-api-endpoints.php
index 6189d404..91c14808 100644
--- a/plugins/jetpack/class.json-api-endpoints.php
+++ b/plugins/jetpack/class.json-api-endpoints.php
@@ -55,7 +55,7 @@ abstract class WPCOM_JSON_API_Endpoint {
// Is this endpoint still in testing phase? If so, not available to the public.
var $in_testing = false;
-
+
/**
* @var string Version of the API
*/
@@ -161,15 +161,16 @@ abstract class WPCOM_JSON_API_Endpoint {
// Get POST body data
function input( $return_default_values = true, $cast_and_filter = true ) {
$input = trim( $this->api->post_body );
-
switch ( $this->api->content_type ) {
+ case 'application/json; charset=utf-8' :
case 'application/json' :
case 'application/x-javascript' :
case 'text/javascript' :
case 'text/x-javascript' :
case 'text/x-json' :
case 'text/json' :
- $return = json_decode( $input );
+ $return = json_decode( $input, true );
+
if ( function_exists( 'json_last_error' ) ) {
if ( JSON_ERROR_NONE !== json_last_error() ) {
return null;
@@ -180,9 +181,6 @@ abstract class WPCOM_JSON_API_Endpoint {
}
}
- if ( is_object( $return ) ) {
- $return = (array) $return;
- }
break;
case 'multipart/form-data' :
$return = array_merge( stripslashes_deep( $_POST ), $_FILES );
@@ -202,6 +200,7 @@ abstract class WPCOM_JSON_API_Endpoint {
function cast_and_filter( $data, $documentation, $return_default_values = false, $for_output = false ) {
$return_as_object = false;
if ( is_object( $data ) ) {
+ // @todo this should probably be a deep copy if $data can ever have nested objects
$data = (array) $data;
$return_as_object = true;
} elseif ( !is_array( $data ) ) {
@@ -446,6 +445,16 @@ abstract class WPCOM_JSON_API_Endpoint {
);
$return[$key] = (object) $this->cast_and_filter( $value, apply_filters( 'wpcom_json_api_attachment_cast_and_filter', $docs ), false, $for_output );
break;
+ case 'metadata' :
+ $docs = array(
+ 'id' => '(int)',
+ 'key' => '(string)',
+ 'value' => '(string|false|float|int|array|object)',
+ 'previous_value' => '(string)',
+ 'operation' => '(string)',
+ );
+ $return[$key] = (object) $this->cast_and_filter( $value, apply_filters( 'wpcom_json_api_attachment_cast_and_filter', $docs ), false, $for_output );
+ break;
default :
trigger_error( "Unknown API casting type {$type['type']}", E_USER_WARNING );
}
@@ -517,7 +526,7 @@ abstract class WPCOM_JSON_API_Endpoint {
'body' => 'Request Parameters',
'response' => 'Response Parameters',
) as $doc_section_key => $label ) :
- $doc_section = 'response' == $doc_section_key ? $doc['response']['body'] : $doc['request'][$doc_section_key];
+ $doc_section = 'response' === $doc_section_key ? $doc['response']['body'] : $doc['request'][$doc_section_key];
if ( !$doc_section ) {
continue;
}
@@ -560,29 +569,26 @@ abstract class WPCOM_JSON_API_Endpoint {
<?php
// If no example was hardcoded in the doc, try to get some
- if ( empty( $this->example_response ) ) {
+ if ( empty( $this->example_response ) ) {
// Examples for endpoint documentation response
$response_key = 'dev_response_' . $this->version . '_' . $this->method . '_' . sanitize_title( $this->path );
- $response = get_option( $response_key );
+ $response = wp_cache_get( $response_key );
// Response doesn't exist, so run the request
- if ( empty( $response ) ) {
+ if ( false === $response ) {
// Only trust GET request
- if ( 'GET' == $this->method ) {
- $response = wp_remote_get( $this->example_request );
- }
-
- // Set as false if it's an error
- if ( is_wp_error( $response ) ) {
- $response = false;
- }
+ if ( 'GET' === $this->method ) {
+ $response = wp_remote_get( $this->example_request );
+ $response_body = wp_remote_retrieve_body( $response );
- // Only update the option if there's a result
- if ( !empty( $response ) ) {
- $response = $response['body'];
- update_option( $response_key, $response );
+ // Only cache if there's a result
+ if ( strlen( $response_body ) ) {
+ wp_cache_set( $response_key, $response );
+ } else {
+ wp_cache_delete( $response_key );
+ }
}
}
@@ -771,7 +777,7 @@ EOPHP;
$type = '(string)';
}
- if ( 'response_format' != $_property ) {
+ if ( 'response_format' !== $_property ) {
// hack - don't show "(default)" in response format
reset( $description );
$description_key = key( $description );
@@ -802,7 +808,7 @@ EOPHP;
$item = compact( 'type', 'description' );
- if ( 'response_format' == $_property ) {
+ if ( 'response_format' === $_property ) {
$doc['response'][$doc_item][$key] = $item;
} else {
$doc['request'][$doc_item][$key] = $item;
@@ -819,7 +825,7 @@ EOPHP;
return false;
}
- if ( 'inherit' == $post->post_status ) {
+ if ( 'inherit' === $post->post_status ) {
$parent_post = get_post( $post->post_parent );
$post_status_obj = get_post_status_object( $parent_post->post_status );
} else {
@@ -849,11 +855,11 @@ EOPHP;
}
if ( -1 == get_option( 'blog_public' ) && !current_user_can( 'read_post', $post->ID ) ) {
- return new WP_Error( 'unauthorized', 'User cannot view post', 403 );
+ return new WP_Error( 'unauthorized', 'User cannot view post', array( 'status_code' => 403, 'error' => 'private_blog' ) );
}
if ( strlen( $post->post_password ) && !current_user_can( 'edit_post', $post->ID ) ) {
- return new WP_Error( 'unauthorized', 'User cannot view password protected post', 403 );
+ return new WP_Error( 'unauthorized', 'User cannot view password protected post', array( 'status_code' => 403, 'error' => 'password_protected' ) );
}
return true;
@@ -876,6 +882,9 @@ EOPHP;
$profile_URL = 'http://en.gravatar.com/' . md5( strtolower( trim( $email ) ) );
} else {
if ( isset( $author->post_author ) ) {
+ if ( 0 == $author->post_author )
+ return null;
+
$author = $author->post_author;
} elseif ( isset( $author->user_id ) && $author->user_id ) {
$author = $author->user_id;
@@ -944,7 +953,7 @@ EOPHP;
$response['description'] = (string) $taxonomy->description;
$response['post_count'] = (int) $taxonomy->count;
- if ( 'category' == $taxonomy_type )
+ if ( 'category' === $taxonomy_type )
$response['parent'] = (int) $taxonomy->parent;
$response['meta'] = (object) array(
@@ -1009,11 +1018,11 @@ EOPHP;
$gmt_offset = get_option( 'gmt_offset' );
$local_time = $time + $gmt_offset * 3600;
-
+
$date = getdate( ( int ) $local_time );
$datetime->setDate( $date['year'], $date['mon'], $date['mday'] );
$datetime->setTime( $date['hours'], $date['minutes'], $date['seconds'] );
-
+
$local = $datetime->format( 'Y-m-d H:i:s' );
return array( (string) $local, (string) $gmt );
}
@@ -1038,7 +1047,7 @@ EOPHP;
}
function get_taxonomy_link( $blog_id, $taxonomy_id, $taxonomy_type, $path = '' ) {
- if ( 'category' == $taxonomy_type )
+ if ( 'category' === $taxonomy_type )
return $this->get_link( '/sites/%d/categories/slug:%s', $blog_id, $taxonomy_id, $path );
else
return $this->get_link( '/sites/%d/tags/slug:%s', $blog_id, $taxonomy_id, $path );
@@ -1091,14 +1100,14 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
),
'password' => '(string) The plaintext password protecting the post, or, more likely, the empty string if the post is not password protected.',
'parent' => "(object>post_reference|false) A reference to the post's parent, if it has one.",
- 'type' => array(
- 'post' => 'A blog post.',
- 'page' => 'A page.',
- ),
+ 'type' => "(string) The post's post_type. Post types besides post and page need to be whitelisted using the <code>rest_api_allowed_post_types</code> filter.",
'comments_open' => '(bool) Is the post open for comments?',
'pings_open' => '(bool) Is the post open for pingbacks, trackbacks?',
'comment_count' => '(int) The number of comments for this post.',
'like_count' => '(int) The number of likes for this post.',
+ 'i_like' => '(bool) Does the current user like this post?',
+ 'is_reblogged' => '(bool) Did the current user reblog this post?',
+ 'is_following' => '(bool) Is the current user following this blog?',
'featured_image' => '(URL) The URL to the featured image for this post if it has one.',
'format' => array(), // see constructor
'geo' => '(object>geo|false)',
@@ -1106,7 +1115,8 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
'tags' => '(object:tag) Hash of tags (keyed by tag name) applied to the post.',
'categories' => '(object:category) Hash of categories (keyed by category name) applied to the post.',
'attachments' => '(object:attachment) Hash of post attachments (keyed by attachment ID).',
- 'meta' => '(object) Meta data',
+ 'metadata' => '(array) Array of post metadata keys and values. All unprotected meta keys are available by default for read requests. Both unprotected and protected meta keys are avaiable for authenticated requests with access. Protected meta keys can be made available with the <code>rest_api_allowed_public_metadata</code> filter.',
+ 'meta' => '(object) API result meta data',
);
// var $response_format =& $this->post_object_format;
@@ -1121,6 +1131,30 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
parent::__construct( $args );
}
+ function is_post_type_allowed( $post_type ) {
+
+ // if the post type is empty, that's fine, WordPress will default to post
+ if ( empty( $post_type ) )
+ return true;
+
+ // whitelist of post types that can be accessed
+ if ( in_array( $post_type, apply_filters( 'rest_api_allowed_post_types', array( 'post', 'page', 'any' ) ) ) )
+ return true;
+
+ return false;
+ }
+
+ function is_metadata_public( $key ) {
+ if ( empty( $key ) )
+ return false;
+
+ // whitelist of metadata that can be accessed
+ if ( in_array( $key, apply_filters( 'rest_api_allowed_public_metadata', array() ) ) )
+ return true;
+
+ return false;
+ }
+
function the_password_form() {
return __( 'This post is password protected.', 'jetpack' );
}
@@ -1134,7 +1168,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
$geo = false;
}
- if ( 'display' == $context ) {
+ if ( 'display' === $context ) {
$args = $this->query_args();
if ( isset( $args['content_width'] ) && $args['content_width'] ) {
$GLOBALS['content_width'] = (int) $args['content_width'];
@@ -1173,8 +1207,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
return new WP_Error( 'unknown_post', 'Unknown post', 404 );
}
- $types = array( 'post', 'page' );
- if ( !in_array( $post->post_type, $types ) ) {
+ if ( ! $this->is_post_type_allowed( $post->post_type ) ) {
return new WP_Error( 'unknown_post', 'Unknown post', 404 );
}
@@ -1200,7 +1233,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
$post = get_post( $post->ID, OBJECT, $context );
$GLOBALS['post'] = $post;
- if ( 'display' == $context ) {
+ if ( 'display' === $context ) {
setup_postdata( $post );
}
@@ -1221,7 +1254,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
$response[$key] = (string) $this->format_date( $post->post_modified_gmt, $post->post_modified );
break;
case 'title' :
- if ( 'display' == $context ) {
+ if ( 'display' === $context ) {
$response[$key] = (string) get_the_title( $post->ID );
} else {
$response[$key] = (string) $post->post_title;
@@ -1234,7 +1267,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
$response[$key] = (string) esc_url_raw( wp_get_shortlink( $post->ID ) );
break;
case 'content' :
- if ( 'display' == $context ) {
+ if ( 'display' === $context ) {
add_filter( 'the_password_form', array( $this, 'the_password_form' ) );
$response[$key] = (string) $this->get_the_post_content_for_display();
remove_filter( 'the_password_form', array( $this, 'the_password_form' ) );
@@ -1243,7 +1276,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
}
break;
case 'excerpt' :
- if ( 'display' == $context ) {
+ if ( 'display' === $context ) {
add_filter( 'the_password_form', array( $this, 'the_password_form' ) );
ob_start();
the_excerpt();
@@ -1289,6 +1322,15 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
case 'like_count' :
$response[$key] = (int) $this->api->post_like_count( $blog_id, $post->ID );
break;
+ case 'i_like' :
+ $response[$key] = (int) $this->api->is_liked( $blog_id, $post->ID );
+ break;
+ case 'is_reblogged':
+ $response[$key] = (int) $this->api->is_reblogged( $blog_id, $post->ID );
+ break;
+ case 'is_following':
+ $response[$key] = (int) $this->api->is_following( $blog_id );
+ break;
case 'featured_image' :
$image_attributes = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
if ( is_array( $image_attributes ) && isset( $image_attributes[0] ) )
@@ -1379,6 +1421,32 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
}
$response[$key] = (object) $response[$key];
break;
+ case 'metadata' : // (array|false)
+ $metadata = array();
+ foreach ( (array) has_meta( $post_id ) as $meta ) {
+ // Don't expose protected fields.
+ $show = false;
+ if ( $this->is_metadata_public( $meta['meta_key'] ) )
+ $show = true;
+ if ( current_user_can( 'edit_post_meta', $post_id , $meta['meta_key'] ) )
+ $show = true;
+
+ if ( !$show )
+ continue;
+
+ $metadata[] = array(
+ 'id' => $meta['meta_id'],
+ 'key' => $meta['meta_key'],
+ 'value' => maybe_unserialize( $meta['meta_value'] ),
+ );
+ }
+
+ if ( ! empty( $metadata ) ) {
+ $response[$key] = $metadata;
+ } else {
+ $response[$key] = false;
+ }
+ break;
case 'meta' :
$response[$key] = (object) array(
'links' => (object) array(
@@ -1462,7 +1530,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
$size = 'win8app-column';
$id = intval( $id );
- if ( 'RAND' == $order )
+ if ( 'RAND' === $order )
$orderby = 'none';
if ( !empty( $include ) ) {
@@ -1481,7 +1549,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
if ( ! empty( $attachments ) ) {
foreach ( $attachments as $id => $attachment ) {
- $link = isset( $attr['link'] ) && 'file' == $attr['link'] ? wp_get_attachment_link( $id, $size, false, false ) : wp_get_attachment_link( $id, $size, true, false );
+ $link = isset( $attr['link'] ) && 'file' === $attr['link'] ? wp_get_attachment_link( $id, $size, false, false ) : wp_get_attachment_link( $id, $size, true, false );
if ( $captiontag && trim($attachment->post_excerpt) ) {
$output .= "<div class='wp-caption aligncenter'>$link
@@ -1509,8 +1577,8 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
'URL' => (string) wp_get_attachment_url( $attachment->ID ),
'guid' => (string) $attachment->guid,
'mime_type' => (string) $attachment->post_mime_type,
- 'width' => (int) $metadata['width'],
- 'height' => (int) $metadata['height'],
+ 'width' => (int) isset( $metadata['width'] ) ? $metadata['width'] : 0,
+ 'height' => (int) isset( $metadata['height'] ) ? $metadata['height'] : 0,
);
if ( isset( $metadata['duration'] ) ) {
@@ -1573,16 +1641,37 @@ class WPCOM_JSON_API_List_Posts_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
return new WP_Error( 'invalid_number', 'The NUMBER parameter must be less than or equal to 100.', 400 );
}
+ if ( ! $this->is_post_type_allowed( $args['type'] ) ) {
+ return new WP_Error( 'unknown_post_type', 'Unknown post type', 404 );
+ }
+
$query = array(
'posts_per_page' => $args['number'],
'order' => $args['order'],
'orderby' => $args['order_by'],
- 'post_type' => $args['type'],
+ 'post_type' => ( 'any' == $args['type'] ) ? array( 'post', 'page' ) : $args['type'],
'post_status' => $args['status'],
'author' => isset( $args['author'] ) && 0 < $args['author'] ? $args['author'] : null,
's' => isset( $args['search'] ) ? $args['search'] : null,
);
+ if ( isset( $args['meta_key'] ) ) {
+ $show = false;
+ if ( $this->is_metadata_public( $args['meta_key'] ) )
+ $show = true;
+ if ( current_user_can( 'edit_post_meta', $query['post_type'], $args['meta_key'] ) )
+ $show = true;
+
+ if ( is_protected_meta( $args['meta_key'], 'post' ) && ! $show )
+ return new WP_Error( 'invalid_meta_key', 'Invalid meta key', 404 );
+
+ $meta = array( 'key' => $args['meta_key'] );
+ if ( isset( $args['meta_value'] ) )
+ $meta['value'] = $args['meta_value'];
+
+ $query['meta_query'] = array( $meta );
+ }
+
if (
isset( $args['sticky'] )
&&
@@ -1735,8 +1824,16 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
}
+ // default to post
+ if ( empty( $input['type'] ) )
+ $input['type'] = 'post';
+
$post_type = get_post_type_object( $input['type'] );
+ if ( ! $this->is_post_type_allowed( $input['type'] ) ) {
+ return new WP_Error( 'unknown_post_type', 'Unknown post type', 404 );
+ }
+
if ( 'publish' === $input['status'] ) {
if ( !current_user_can( $post_type->cap->publish_posts ) ) {
if ( current_user_can( $post_type->cap->edit_posts ) ) {
@@ -1782,12 +1879,21 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
if ( !empty( $input['categories'] )) {
if ( is_array( $input['categories'] ) ) {
- $categories = $input['categories'];
+ $_categories = $input['categories'];
} else {
foreach ( explode( ',', $input['categories'] ) as $category ) {
- $categories[] = $category;
+ $_categories[] = $category;
}
}
+ foreach ( $_categories as $category ) {
+ if ( !$category_info = term_exists( $category, 'category' ) ) {
+ if ( is_int( $category ) )
+ continue;
+ $category_info = wp_insert_term( $category, 'category' );
+ }
+ if ( !is_wp_error( $category_info ) )
+ $categories[] = (int) $category_info['term_id'];
+ }
}
if ( !empty( $input['tags'] ) ) {
@@ -1802,9 +1908,9 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
}
unset( $input['tags'], $input['categories'] );
-
+
$insert = array();
-
+
if ( !empty( $input['slug'] ) ) {
$insert['post_name'] = $input['slug'];
unset( $input['slug'] );
@@ -1814,22 +1920,30 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
$insert['comment_status'] = 'open';
else if ( false === $input['comments_open'] )
$insert['comment_status'] = 'closed';
-
+
if ( true === $input['pings_open'] )
$insert['ping_status'] = 'open';
else if ( false === $input['pings_open'] )
$insert['ping_status'] = 'closed';
-
+
unset( $input['comments_open'], $input['pings_open'] );
-
+
$publicize = $input['publicize'];
$publicize_custom_message = $input['publicize_message'];
unset( $input['publicize'], $input['publicize_message'] );
-
+
+ $metadata = $input['metadata'];
+ unset( $input['metadata'] );
+
foreach ( $input as $key => $value ) {
$insert["post_$key"] = $value;
}
-
+
+ if ( !empty( $tags ) )
+ $insert["tax_input"]["post_tag"] = $tags;
+ if ( !empty( $categories ) )
+ $insert["tax_input"]["category"] = $categories;
+
$has_media = isset( $input['media'] ) && $input['media'] ? count( $input['media'] ) : false;
if ( $new ) {
@@ -1868,9 +1982,9 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
}
if ( !$post_id || is_wp_error( $post_id ) ) {
- return null;
+ return $post_id;
}
-
+
if ( $publicize === false ) {
foreach ( $GLOBALS['publicize_ui']->publicize->get_services( 'all' ) as $name => $service ) {
update_post_meta( $post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name, 1 );
@@ -1882,17 +1996,80 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
}
}
}
-
+
if ( !empty( $publicize_custom_message ) )
- update_post_meta( $post_id, $GLOBALS['publicize_ui']->publicize->POST_MESS, trim( $publicize_custom_message ) );
-
- if ( is_array( $categories ) )
- wp_set_object_terms( $post_id, $categories, 'category' );
- if ( is_array( $tags ) )
- wp_set_object_terms( $post_id, $tags, 'post_tag' );
+ update_post_meta( $post_id, $GLOBALS['publicize_ui']->publicize->POST_MESS, trim( $publicize_custom_message ) );
set_post_format( $post_id, $insert['post_format'] );
+ if ( ! empty( $metadata ) ) {
+ foreach ( (array) $metadata as $meta ) {
+
+ $meta = (object) $meta;
+
+ $existing_meta_item = new stdClass;
+
+ if ( empty( $meta->operation ) )
+ $meta->operation = 'update';
+
+ if ( ! empty( $meta->value ) ) {
+ if ( 'true' == $meta->value )
+ $meta->value = true;
+ if ( 'false' == $meta->value )
+ $meta->value = false;
+ }
+
+ if ( ! empty( $meta->id ) ) {
+ $meta->id = absint( $meta->id );
+ $existing_meta_item = get_metadata_by_mid( 'post', $meta->id );
+ }
+
+ $unslashed_meta_key = wp_unslash( $meta->key ); // should match what the final key will be
+ $meta->key = wp_slash( $meta->key );
+ $unslashed_existing_meta_key = wp_unslash( $existing_meta_item->meta_key );
+ $existing_meta_item->meta_key = wp_slash( $existing_meta_item->meta_key );
+
+ switch ( $meta->operation ) {
+ case 'delete':
+
+ if ( ! empty( $meta->id ) && ! empty( $existing_meta_item->meta_key ) && current_user_can( 'delete_post_meta', $post_id, $unslashed_existing_meta_key ) ) {
+ delete_metadata_by_mid( 'post', $meta->id );
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->previous_value ) && current_user_can( 'delete_post_meta', $post_id, $unslashed_meta_key ) ) {
+ delete_post_meta( $post_id, $meta->key, $meta->previous_value );
+ } elseif ( ! empty( $meta->key ) && current_user_can( 'delete_post_meta', $post_id, $unslashed_meta_key ) ) {
+ delete_post_meta( $post_id, $meta->key );
+ }
+
+ break;
+ case 'add':
+
+ if ( ! empty( $meta->id ) || ! empty( $meta->previous_value ) ) {
+ continue;
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->value ) && current_user_can( 'add_post_meta', $post_id, $unslashed_meta_key ) ) {
+ add_post_meta( $post_id, $meta->key, $meta->value );
+ }
+
+ break;
+ case 'update':
+
+ if ( empty( $meta->value ) ) {
+ continue;
+ } elseif ( ! empty( $meta->id ) && ! empty( $existing_meta_item->meta_key ) && current_user_can( 'edit_post_meta', $post_id, $unslashed_existing_meta_key ) ) {
+ update_metadata_by_mid( 'post', $meta->id, $meta->value );
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->previous_value ) && current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) ) {
+ update_post_meta( $post_id, $meta->key,$meta->value, $meta->previous_value );
+ } elseif ( ! empty( $meta->key ) && current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) ) {
+ update_post_meta( $post_id, $meta->key, $meta->value );
+ }
+
+ break;
+ }
+
+ }
+ }
+
+ do_action( 'rest_api_inserted_post', $post_id, $insert, $new );
+
$return = $this->get_post_by( 'ID', $post_id, $args['context'] );
if ( !$return || is_wp_error( $return ) ) {
return $return;
@@ -1910,6 +2087,10 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
return new WP_Error( 'unknown_post', 'Unknown post', 404 );
}
+ if ( ! $this->is_post_type_allowed( $post->post_type ) ) {
+ return new WP_Error( 'unknown_post_type', 'Unknown post type', 404 );
+ }
+
if ( !current_user_can( 'delete_post', $post->ID ) ) {
return new WP_Error( 'unauthorized', 'User cannot delete posts', 403 );
}
@@ -2039,7 +2220,7 @@ class WPCOM_JSON_API_Update_Taxonomy_Endpoint extends WPCOM_JSON_API_Taxonomy_En
return new WP_Error( 'unknown_taxonomy', 'A taxonomy with that name already exists', 404 );
}
- if ( 'category' != $taxonomy_type )
+ if ( 'category' !== $taxonomy_type )
$input['parent'] = 0;
$data = wp_insert_term( addslashes( $input['name'] ), $taxonomy_type,
@@ -2048,8 +2229,12 @@ class WPCOM_JSON_API_Update_Taxonomy_Endpoint extends WPCOM_JSON_API_Taxonomy_En
'parent' => $input['parent']
)
);
-
+
+ if ( is_wp_error( $data ) )
+ return $data;
+
$taxonomy = get_term_by( 'id', $data['term_id'], $taxonomy_type );
+
$return = $this->get_taxonomy( $taxonomy->slug, $taxonomy_type, $args['context'] );
if ( !$return || is_wp_error( $return ) ) {
return $return;
@@ -2081,7 +2266,7 @@ class WPCOM_JSON_API_Update_Taxonomy_Endpoint extends WPCOM_JSON_API_Taxonomy_En
}
$update = array();
- if ( 'category' == $taxonomy_type && !empty( $input['parent'] ) )
+ if ( 'category' === $taxonomy_type && !empty( $input['parent'] ) )
$update['parent'] = $input['parent'];
if ( !empty( $input['description'] ) )
@@ -2093,7 +2278,7 @@ class WPCOM_JSON_API_Update_Taxonomy_Endpoint extends WPCOM_JSON_API_Taxonomy_En
$data = wp_update_term( $taxonomy->term_id, $taxonomy_type, $update );
$taxonomy = get_term_by( 'id', $data['term_id'], $taxonomy_type );
-
+
$return = $this->get_taxonomy( $taxonomy->slug, $taxonomy_type, $args['context'] );
if ( !$return || is_wp_error( $return ) ) {
return $return;
@@ -2266,7 +2451,7 @@ abstract class WPCOM_JSON_API_Comment_Endpoint extends WPCOM_JSON_API_Endpoint {
$response[$key] = (string) esc_url_raw( wp_get_shortlink( $post->ID ) . "%23comment-{$comment->comment_ID}" );
break;
case 'content' :
- if ( 'display' == $context ) {
+ if ( 'display' === $context ) {
ob_start();
comment_text();
$response[$key] = (string) ob_get_clean();
@@ -2694,17 +2879,28 @@ class WPCOM_JSON_API_Update_Comment_Endpoint extends WPCOM_JSON_API_Comment_Endp
}
if ( isset( $update['comment_status'] ) ) {
+ if ( count( $update ) === 1 ) {
+ // We are only here to update the comment status so let's respond ASAP
+ add_action( 'wp_set_comment_status', array( $this, 'output_comment' ), 0, 1 );
+ }
switch ( $update['comment_status'] ) {
+ case 'approved' :
+ if ( 'approve' !== $comment_status ) {
+ wp_set_comment_status( $comment->comment_ID, 'approve' );
+ }
+ break;
case 'unapproved' :
- $update['comment_approved'] = 0;
+ if ( 'hold' !== $comment_status ) {
+ wp_set_comment_status( $comment->comment_ID, 'hold' );
+ }
break;
case 'spam' :
- if ( 'spam' != $comment_status ) {
+ if ( 'spam' !== $comment_status ) {
wp_spam_comment( $comment->comment_ID );
}
break;
case 'unspam' :
- if ( 'spam' == $comment_status ) {
+ if ( 'spam' === $comment_status ) {
wp_unspam_comment( $comment->comment_ID );
}
break;
@@ -2713,12 +2909,12 @@ class WPCOM_JSON_API_Update_Comment_Endpoint extends WPCOM_JSON_API_Comment_Endp
return new WP_Error( 'trash_disabled', 'Cannot trash comment', 403 );
}
- if ( 'trash' != $comment_status ) {
+ if ( 'trash' !== $comment_status ) {
wp_trash_comment( $comment_id );
}
break;
case 'untrash' :
- if ( 'trash' == $comment_status ) {
+ if ( 'trash' === $comment_status ) {
wp_untrash_comment( $comment->comment_ID );
}
break;
@@ -2729,9 +2925,10 @@ class WPCOM_JSON_API_Update_Comment_Endpoint extends WPCOM_JSON_API_Comment_Endp
unset( $update['comment_status'] );
}
- $update['comment_ID'] = $comment->comment_ID;
-
- wp_update_comment( add_magic_quotes( $update ) );
+ if ( ! empty( $update ) ) {
+ $update['comment_ID'] = $comment->comment_ID;
+ wp_update_comment( add_magic_quotes( $update ) );
+ }
$return = $this->get_comment( $comment->comment_ID, $args['context'] );
if ( !$return || is_wp_error( $return ) ) {
@@ -2770,6 +2967,12 @@ class WPCOM_JSON_API_Update_Comment_Endpoint extends WPCOM_JSON_API_Comment_Endp
return $this->get_comment( $comment->comment_ID, $args['context'] );
}
+
+ function output_comment( $comment_id ) {
+ $args = $this->query_args();
+ $output = $this->get_comment( $comment_id, $args['context'] );
+ $this->api->output_early( 200, $output );
+ }
}
class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
@@ -2838,16 +3041,20 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
}
}
+
+
/*
* Set up endpoints
*/
+
+
/*
* Site endpoints
*/
new WPCOM_JSON_API_GET_Site_Endpoint( array(
'description' => 'Information about a site ID/domain',
- 'group' => 'Sites',
+ 'group' => 'sites',
'stat' => 'sites:X',
'method' => 'GET',
@@ -2880,7 +3087,7 @@ new WPCOM_JSON_API_GET_Site_Endpoint( array(
*/
new WPCOM_JSON_API_List_Posts_Endpoint( array(
'description' => 'Return matching Posts',
- 'group' => 'Posts',
+ 'group' => 'posts',
'stat' => 'posts',
'method' => 'GET',
@@ -2907,11 +3114,7 @@ new WPCOM_JSON_API_List_Posts_Endpoint( array(
'before' => '(ISO 8601 datetime) Return posts dated on or before the specified datetime.',
'tag' => '(string) Specify the tag name or slug.',
'category' => '(string) Specify the category name or slug.',
- 'type' => array(
- 'post' => 'Return only blog posts.',
- 'page' => 'Return only pages.',
- 'any' => 'Return both blog posts and pages.',
- ),
+ 'type' => "(string) Specify the post type. Defaults to 'post', use 'any' to query for both posts and pages. Post types besides post and page need to be whitelisted using the <code>rest_api_allowed_post_types</code> filter.",
'status' => array(
'publish' => 'Return only published posts.',
'private' => 'Return only private posts.',
@@ -2924,6 +3127,8 @@ new WPCOM_JSON_API_List_Posts_Endpoint( array(
'sticky' => '(bool) Specify the stickiness.',
'author' => "(int) Author's user ID",
'search' => '(string) Search query',
+ 'meta_key' => '(string) Metadata key that the post should contain',
+ 'meta_value' => '(string) Metadata value that the post should contain. Will only be applied if a `meta_key` is also given',
),
'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/en.blog.wordpress.com/posts/?number=5&pretty=1'
@@ -2931,7 +3136,7 @@ new WPCOM_JSON_API_List_Posts_Endpoint( array(
new WPCOM_JSON_API_Get_Post_Endpoint( array(
'description' => 'Return a single Post (by ID)',
- 'group' => 'Posts',
+ 'group' => 'posts',
'stat' => 'posts:1',
'method' => 'GET',
@@ -2961,7 +3166,7 @@ new WPCOM_JSON_API_Get_Post_Endpoint( array(
new WPCOM_JSON_API_Get_Post_Endpoint( array(
'description' => 'Return a single Post (by slug)',
- 'group' => 'Posts',
+ 'group' => 'posts',
'stat' => 'posts:slug',
'method' => 'GET',
@@ -2976,7 +3181,7 @@ new WPCOM_JSON_API_Get_Post_Endpoint( array(
new WPCOM_JSON_API_Update_Post_Endpoint( array(
'description' => 'Create a Post',
- 'group' => 'Posts',
+ 'group' => 'posts',
'stat' => 'posts:new',
'method' => 'POST',
@@ -3002,15 +3207,13 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
),
'password' => '(string) The plaintext password protecting the post, or, more likely, the empty string if the post is not password protected.',
'parent' => "(int) The post ID of the new post's parent.",
- 'type' => array(
- 'post' => 'Create a blog post.',
- 'page' => 'Create a page.',
- ),
+ 'type' => "(string) The post type. Defaults to 'post'. Post types besides post and page need to be whitelisted using the <code>rest_api_allowed_post_types</code> filter.",
'categories' => "(array|string) Comma separated list or array of categories (name or id)",
'tags' => "(array|string) Comma separated list or array of tags (name or id)",
'format' => get_post_format_strings(),
'media' => "(media) An array of images to attach to the post. To upload media, the entire request should be multipart/form-data encoded. Multiple media items will be displayed in a gallery. Accepts images (image/gif, image/jpeg, image/png) only.<br /><br /><strong>Example</strong>:<br />" .
"<code>curl \<br />--form 'title=Image' \<br />--form 'media[]=@/path/to/file.jpg' \<br />-H 'Authorization: BEARER your-token' \<br />'https://public-api.wordpress.com/rest/v1/sites/123/posts/new'</code>",
+ 'metadata' => "(array) Array of metadata objects containing the following properties: `key` (metadata key), `id` (meta ID), `previous_value` (if set, the action will only occur for the provided previous value), `value` (the new value to set the meta to), `operation` (the operation to perform: `update` or `add`; defaults to `update`). All unprotected meta keys are available by default for read requests. Both unprotected and protected meta keys are avaiable for authenticated requests with access. Protected meta keys can be made available with the <code>rest_api_allowed_public_metadata</code> filter.",
'comments_open' => "(bool) Should the post be open to comments? Defaults to the blog's preference.",
'pings_open' => "(bool) Should the post be open to comments? Defaults to the blog's preference.",
),
@@ -3026,7 +3229,7 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
'title' => 'Hello World',
'content' => 'Hello. I am a test post. I was created by the API',
'tags' => 'tests',
- 'categories' => 'API'
+ 'categories' => 'API'
)
),
@@ -3056,11 +3259,14 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
"pings_open": true,
"comment_count": 0,
"like_count": 0,
+ "i_like": false,
+ "is_reblogged": false,
+ "is_following": false,
"featured_image": "",
"format": "standard",
"geo": false,
"publicize_URLs": [
-
+
],
"tags": {
"tests": {
@@ -3093,6 +3299,13 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
}
}
},
+ "metadata {
+ {
+ "id" : 123,
+ "key" : "test_meta_key",
+ "value" : "test_value",
+ }
+ },
"meta": {
"links": {
"self": "https:\/\/public-api.wordpress.com\/rest\/v1\/sites\/30434183\/posts\/1270",
@@ -3107,7 +3320,7 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
new WPCOM_JSON_API_Update_Post_Endpoint( array(
'description' => 'Edit a Post',
- 'group' => 'Posts',
+ 'group' => 'posts',
'stat' => 'posts:1:POST',
'method' => 'POST',
@@ -3138,6 +3351,7 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
'format' => get_post_format_strings(),
'comments_open' => '(bool) Should the post be open to comments?',
'pings_open' => '(bool) Should the post be open to comments?',
+ 'metadata' => "(array) Array of metadata objects containing the following properties: `key` (metadata key), `id` (meta ID), `previous_value` (if set, the action will only occur for the provided previous value), `value` (the new value to set the meta to), `operation` (the operation to perform: `update` or `add`; defaults to `update`). All unprotected meta keys are available by default for read requests. Both unprotected and protected meta keys are avaiable for authenticated requests with access. Protected meta keys can be made available with the <code>rest_api_allowed_public_metadata</code> filter.",
),
'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/30434183/posts/1222/',
@@ -3151,7 +3365,7 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
'title' => 'Hello World (Again)',
'content' => 'Hello. I am an edited post. I was edited by the API',
'tags' => 'tests',
- 'categories' => 'API'
+ 'categories' => 'API'
)
),
@@ -3181,11 +3395,14 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
"pings_open": true,
"comment_count": 5,
"like_count": 0,
+ "i_like": false,
+ "is_reblogged": false,
+ "is_following": false,
"featured_image": "",
"format": "standard",
"geo": false,
"publicize_URLs": [
-
+
],
"tags": {
"tests": {
@@ -3218,6 +3435,13 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
}
}
},
+ "metadata {
+ {
+ "id" : 123,
+ "key" : "test_meta_key",
+ "value" : "test_value",
+ }
+ },
"meta": {
"links": {
"self": "https:\/\/public-api.wordpress.com\/rest\/v1\/sites\/30434183\/posts\/1222",
@@ -3232,8 +3456,8 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
) );
new WPCOM_JSON_API_Update_Post_Endpoint( array(
- 'description' => 'Delete a Post',
- 'group' => 'Posts',
+ 'description' => 'Delete a Post. Note: If the post object is of type post or page and the trash is enabled, this request will send the post to the trash. A second request will permanently delete the post.',
+ 'group' => 'posts',
'stat' => 'posts:1:delete',
'method' => 'POST',
@@ -3277,11 +3501,14 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
"pings_open": true,
"comment_count": 5,
"like_count": 0,
+ "i_like": false,
+ "is_reblogged": false,
+ "is_following": false,
"featured_image": "",
"format": "standard",
"geo": false,
"publicize_URLs": [
-
+
],
"tags": {
"tests": {
@@ -3298,6 +3525,13 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
}
}
},
+ "metadata {
+ {
+ "id" : 123,
+ "key" : "test_meta_key",
+ "value" : "test_value",
+ }
+ },
"categories": {
"API": {
"name": "API",
@@ -3332,7 +3566,7 @@ new WPCOM_JSON_API_Update_Post_Endpoint( array(
*/
new WPCOM_JSON_API_List_Comments_Endpoint( array(
'description' => 'Return recent Comments',
- 'group' => 'Comments',
+ 'group' => 'comments',
'stat' => 'comments',
'method' => 'GET',
@@ -3346,7 +3580,7 @@ new WPCOM_JSON_API_List_Comments_Endpoint( array(
new WPCOM_JSON_API_List_Comments_Endpoint( array(
'description' => 'Return recent Comments for a Post',
- 'group' => 'Comments',
+ 'group' => 'comments',
'stat' => 'posts:1:replies',
'method' => 'GET',
@@ -3361,7 +3595,7 @@ new WPCOM_JSON_API_List_Comments_Endpoint( array(
new WPCOM_JSON_API_Get_Comment_Endpoint( array(
'description' => 'Return a single Comment',
- 'group' => 'Comments',
+ 'group' => 'comments',
'stat' => 'comments:1',
'method' => 'GET',
@@ -3376,7 +3610,7 @@ new WPCOM_JSON_API_Get_Comment_Endpoint( array(
new WPCOM_JSON_API_Update_Comment_Endpoint( array(
'description' => 'Create a Comment on a Post',
- 'group' => 'Comments',
+ 'group' => 'comments',
'stat' => 'posts:1:replies:new',
'method' => 'POST',
@@ -3447,7 +3681,7 @@ new WPCOM_JSON_API_Update_Comment_Endpoint( array(
new WPCOM_JSON_API_Update_Comment_Endpoint( array(
'description' => 'Create a Comment as a reply to another Comment',
- 'group' => 'Comments',
+ 'group' => 'comments',
'stat' => 'comments:1:replies:new',
'method' => 'POST',
@@ -3517,7 +3751,7 @@ new WPCOM_JSON_API_Update_Comment_Endpoint( array(
new WPCOM_JSON_API_Update_Comment_Endpoint( array(
'description' => 'Edit a Comment',
- 'group' => 'Comments',
+ 'group' => 'comments',
'stat' => 'comments:1:POST',
'method' => 'POST',
@@ -3592,7 +3826,7 @@ new WPCOM_JSON_API_Update_Comment_Endpoint( array(
new WPCOM_JSON_API_Update_Comment_Endpoint( array(
'description' => 'Delete a Comment',
- 'group' => 'Comments',
+ 'group' => 'comments',
'stat' => 'comments:1:delete',
'method' => 'POST',
@@ -3654,7 +3888,7 @@ new WPCOM_JSON_API_Update_Comment_Endpoint( array(
*/
new WPCOM_JSON_API_Get_Taxonomy_Endpoint( array(
'description' => 'Returns information on a single Category',
- 'group' => 'Taxonomy',
+ 'group' => 'taxonomy',
'stat' => 'categories:1',
'method' => 'GET',
@@ -3669,7 +3903,7 @@ new WPCOM_JSON_API_Get_Taxonomy_Endpoint( array(
new WPCOM_JSON_API_Get_Taxonomy_Endpoint( array(
'description' => 'Returns information on a single Tag',
- 'group' => 'Taxonomy',
+ 'group' => 'taxonomy',
'stat' => 'tags:1',
'method' => 'GET',
@@ -3684,7 +3918,7 @@ new WPCOM_JSON_API_Get_Taxonomy_Endpoint( array(
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
'description' => 'Create a new Category',
- 'group' => 'Taxonomy',
+ 'group' => 'taxonomy',
'stat' => 'categories:new',
'method' => 'POST',
@@ -3727,7 +3961,7 @@ new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
'description' => 'Create a new Tag',
- 'group' => 'Taxonomy',
+ 'group' => 'taxonomy',
'stat' => 'tags:new',
'method' => 'POST',
@@ -3769,7 +4003,7 @@ new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
'description' => 'Edit a Tag',
- 'group' => 'Taxonomy',
+ 'group' => 'taxonomy',
'stat' => 'tags:1:POST',
'method' => 'POST',
@@ -3812,7 +4046,7 @@ new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
'description' => 'Edit a Category',
- 'group' => 'Taxonomy',
+ 'group' => 'taxonomy',
'stat' => 'categories:1:POST',
'method' => 'POST',
@@ -3857,7 +4091,7 @@ new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
'description' => 'Delete a Category',
- 'group' => 'Taxonomy',
+ 'group' => 'taxonomy',
'stat' => 'categories:1:delete',
'method' => 'POST',
@@ -3885,7 +4119,7 @@ new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
new WPCOM_JSON_API_Update_Taxonomy_Endpoint( array(
'description' => 'Delete a Tag',
- 'group' => 'Taxonomy',
+ 'group' => 'taxonomy',
'stat' => 'tags:1:delete',
'method' => 'POST',
diff --git a/plugins/jetpack/class.json-api.php b/plugins/jetpack/class.json-api.php
index 5a322eb6..b94ce590 100644
--- a/plugins/jetpack/class.json-api.php
+++ b/plugins/jetpack/class.json-api.php
@@ -12,6 +12,7 @@ class WPCOM_JSON_API {
var $method = '';
var $url = '';
var $path = '';
+ var $version = null;
var $query = array();
var $post_body = null;
var $files = null;
@@ -23,6 +24,7 @@ class WPCOM_JSON_API {
var $public_api_scheme = 'https';
var $trapped_error = null;
+ var $did_output = false;
static function init( $method = null, $url = null, $post_body = null ) {
if ( !self::$self ) {
@@ -78,7 +80,7 @@ class WPCOM_JSON_API {
$this->accept = $_SERVER['HTTP_ACCEPT'];
}
- if ( 'POST' == $this->method ) {
+ if ( 'POST' === $this->method ) {
if ( is_null( $post_body ) ) {
$this->post_body = file_get_contents( 'php://input' );
@@ -122,11 +124,17 @@ class WPCOM_JSON_API {
add_filter( 'comment_edit_pre', array( $this, 'comment_edit_pre' ) );
- $this->initialize();
+ $initialization = $this->initialize();
+ if ( is_wp_error( $initialization ) ) {
+ $this->output_error( $initialization );
+ return;
+ }
- // Normalize path
+ // Normalize path and extract API version
$this->path = untrailingslashit( $this->path );
- $this->path = preg_replace( '#^/rest/v1#', '', $this->path );
+ preg_match( '#^/rest/v1(\.\d+)*#', $this->path, $matches );
+ $this->path = substr( $this->path, strlen( $matches[0] ) );
+ $this->version = $matches[1];
$allowed_methods = array( 'GET', 'POST' );
$four_oh_five = false;
@@ -156,7 +164,7 @@ class WPCOM_JSON_API {
$methods = $allowed_methods;
$find_all_matching_endpoints = true;
$four_oh_five = true;
- }
+ }
}
// Find which endpoint to serve
@@ -238,25 +246,37 @@ class WPCOM_JSON_API {
if ( !$response ) {
return $this->output( 500, '', 'text/plain' );
} elseif ( is_wp_error( $response ) ) {
- $status_code = $response->get_error_data();
- if ( !$status_code ) {
- $status_code = 400;
- }
- $response = array(
- 'error' => $response->get_error_code(),
- 'message' => $response->get_error_message(),
- );
- return $this->output( $status_code, $response );
+ return $this->output_error( $response );
}
return $this->output( 200, $response );
}
function process_request( WPCOM_JSON_API_Endpoint $endpoint, $path_pieces ) {
+ $this->endpoint = $endpoint;
return call_user_func_array( array( $endpoint, 'callback' ), $path_pieces );
}
+ function output_early( $status_code, $response = null, $content_type = 'application/json' ) {
+ $exit = $this->exit;
+ $this->exit = false;
+ if ( is_wp_error( $response ) )
+ $this->output_error( $response );
+ else
+ $this->output( $status_code, $response, $content_type );
+ $this->exit = $exit;
+ $this->finish_request();
+ }
+
function output( $status_code, $response = null, $content_type = 'application/json' ) {
+ // In case output() was called before the callback returned
+ if ( $this->did_output ) {
+ if ( $this->exit )
+ exit;
+ return $content_type;
+ }
+ $this->did_output = true;
+
if ( is_null( $response ) ) {
$response = new stdClass;
}
@@ -310,6 +330,22 @@ class WPCOM_JSON_API {
return $content_type;
}
+ function output_error( $error ) {
+ $status_code = $error->get_error_data();
+
+ if ( is_array( $status_code ) )
+ $status_code = $status_code['status_code'];
+
+ if ( !$status_code ) {
+ $status_code = 400;
+ }
+ $response = array(
+ 'error' => $error->get_error_code(),
+ 'message' => $error->get_error_message(),
+ );
+ return $this->output( $status_code, $response );
+ }
+
function ensure_http_scheme_of_home_url( $url, $path, $original_scheme ) {
if ( $original_scheme ) {
return $url;
@@ -352,6 +388,18 @@ class WPCOM_JSON_API {
return 0;
}
+ function is_liked( $blog_id, $post_id ) {
+ return false;
+ }
+
+ function is_reblogged( $blog_id, $post_id ) {
+ return false;
+ }
+
+ function is_following( $blog_id ) {
+ return false;
+ }
+
function get_avatar_url( $email ) {
add_filter( 'pre_option_show_avatars', '__return_true', 999 );
$_SERVER['HTTPS'] = 'off';
@@ -440,4 +488,9 @@ class WPCOM_JSON_API {
'message' => $this->trapped_error['message'],
) );
}
+
+ function finish_request() {
+ if ( function_exists( 'fastcgi_finish_request' ) )
+ return fastcgi_finish_request();
+ }
}
diff --git a/plugins/jetpack/class.photon.php b/plugins/jetpack/class.photon.php
index c0456885..b7e2ddfa 100644
--- a/plugins/jetpack/class.photon.php
+++ b/plugins/jetpack/class.photon.php
@@ -135,7 +135,7 @@ class Jetpack_Photon {
$images = Jetpack_Photon::parse_images_from_html( $content );
if ( ! empty( $images ) ) {
- global $content_width;
+ $content_width = Jetpack::get_content_width();
$image_sizes = self::image_sizes();
$upload_dir = wp_upload_dir();
@@ -309,6 +309,10 @@ class Jetpack_Photon {
// Replace original tag with modified version
$content = str_replace( $tag, $new_tag, $content );
}
+ } elseif ( preg_match( '#^http(s)?://i[\d]{1}.wp.com#', $src ) && ! empty( $images['link_url'][ $index ] ) && self::validate_image_url( $images['link_url'][ $index ] ) ) {
+ $new_tag = preg_replace( '#(href=["|\'])' . $images['link_url'][ $index ] . '(["|\'])#i', '\1' . jetpack_photon_url( $images['link_url'][ $index ] ) . '\2', $tag, 1 );
+
+ $content = str_replace( $tag, $new_tag, $content );
}
}
}
diff --git a/plugins/jetpack/functions.gallery.php b/plugins/jetpack/functions.gallery.php
index 9a9e71b5..fd9319ed 100644
--- a/plugins/jetpack/functions.gallery.php
+++ b/plugins/jetpack/functions.gallery.php
@@ -9,10 +9,10 @@ class Jetpack_Gallery_Settings {
}
function admin_init() {
- $this->gallery_types = apply_filters( 'jetpack_gallery_types', array() );
+ $this->gallery_types = apply_filters( 'jetpack_gallery_types', array( 'default' => __( 'Thumbnail Grid', 'jetpack' ) ) );
// Enqueue the media UI only if needed.
- if ( ! empty( $this->gallery_types ) ) {
+ if ( count( $this->gallery_types ) > 1 ) {
add_action( 'wp_enqueue_media', array( $this, 'wp_enqueue_media' ) );
add_action( 'print_media_templates', array( $this, 'print_media_templates' ) );
}
@@ -32,14 +32,15 @@ class Jetpack_Gallery_Settings {
* Outputs a view template which can be used with wp.media.template
*/
function print_media_templates() {
+ $default_gallery_type = apply_filters( 'jetpack_default_gallery_type', 'default' );
+
?>
<script type="text/html" id="tmpl-jetpack-gallery-settings">
<label class="setting">
<span><?php _e( 'Type', 'jetpack' ); ?></span>
<select class="type" name="type" data-setting="type">
- <option value="default" <?php selected( true ); ?>><?php _e( 'Default', 'jetpack' ); ?></option>
<?php foreach ( $this->gallery_types as $value => $caption ) : ?>
- <option value="<?php echo esc_attr( $value ); ?>"><?php echo esc_html( $caption ); ?></option>
+ <option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $default_gallery_type ); ?>><?php echo esc_html( $caption ); ?></option>
<?php endforeach; ?>
</select>
</label>
diff --git a/plugins/jetpack/functions.opengraph.php b/plugins/jetpack/functions.opengraph.php
index 542d01f1..ef610af9 100644
--- a/plugins/jetpack/functions.opengraph.php
+++ b/plugins/jetpack/functions.opengraph.php
@@ -22,14 +22,14 @@ function jetpack_og_tags() {
$og_output = "\n<!-- Jetpack Open Graph Tags -->\n";
$tags = array();
- $image_width = absint( apply_filters( 'jetpack_open_graph_image_width', 200 ) );
- $image_height = absint( apply_filters( 'jetpack_open_graph_image_height', 200 ) );
+ $image_width = absint( apply_filters( 'jetpack_open_graph_image_width', 200 ) );
+ $image_height = absint( apply_filters( 'jetpack_open_graph_image_height', 200 ) );
$description_length = 197;
if ( is_home() || is_front_page() ) {
- $site_type = get_option( 'open_graph_protocol_site_type' );
- $tags['og:type'] = ! empty( $site_type ) ? $site_type : 'blog';
- $tags['og:title'] = get_bloginfo( 'name' );
+ $site_type = get_option( 'open_graph_protocol_site_type' );
+ $tags['og:type'] = ! empty( $site_type ) ? $site_type : 'blog';
+ $tags['og:title'] = get_bloginfo( 'name' );
$tags['og:description'] = get_bloginfo( 'description' );
$front_page_id = get_option( 'page_for_posts' );
@@ -44,13 +44,15 @@ function jetpack_og_tags() {
$tags['fb:admins'] = $facebook_admins;
} else if ( is_author() ) {
- $tags['og:type'] = 'author';
+ $tags['og:type'] = 'profile';
$author = get_queried_object();
- $tags['og:title'] = $author->display_name;
- $tags['og:url'] = get_author_posts_url( $author->ID );
- $tags['og:description'] = $author->description;
+ $tags['og:title'] = $author->display_name;
+ $tags['og:url'] = get_author_posts_url( $author->ID );
+ $tags['og:description'] = $author->description;
+ $tags['profile:first_name'] = get_the_author_meta( 'first_name', $author->ID );
+ $tags['profile:last_name'] = get_the_author_meta( 'last_name', $author->ID );
} else if ( is_singular() ) {
global $post;
@@ -72,7 +74,7 @@ function jetpack_og_tags() {
return;
$tags['og:site_name'] = get_bloginfo( 'name' );
- $tags['og:image'] = jetpack_og_get_image( $image_width, $image_height );
+ $tags['og:image'] = jetpack_og_get_image( $image_width, $image_height );
// Facebook whines if you give it an empty title
if ( empty( $tags['og:title'] ) )
@@ -101,7 +103,7 @@ function jetpack_og_tags() {
echo $og_output;
}
-function jetpack_og_get_image( $width = 50, $height = 50, $max_images = 4 ) { // Facebook requires thumbnails to be a minimum of 50x50
+function jetpack_og_get_image( $width = 200, $height = 200, $max_images = 4 ) { // Facebook requires thumbnails to be a minimum of 200x200
$image = '';
if ( is_singular() && !is_home() && !is_front_page() ) {
diff --git a/plugins/jetpack/functions.photon.php b/plugins/jetpack/functions.photon.php
index fc276b31..bce3b912 100644
--- a/plugins/jetpack/functions.photon.php
+++ b/plugins/jetpack/functions.photon.php
@@ -80,7 +80,7 @@ function jetpack_photon_url( $image_url, $args = array(), $scheme = null ) {
return jetpack_photon_url_scheme( $photon_url, $scheme );
}
-
+add_filter( 'jetpack_photon_url', 'jetpack_photon_url', 10, 3 );
/**
* WordPress.com
@@ -157,4 +157,4 @@ function jetpack_photon_allow_facebook_graph_domain( $allow = false, $domain ) {
}
return $allow;
-} \ No newline at end of file
+}
diff --git a/plugins/jetpack/jetpack.php b/plugins/jetpack/jetpack.php
index 80b6a3ce..7c0fa023 100644
--- a/plugins/jetpack/jetpack.php
+++ b/plugins/jetpack/jetpack.php
@@ -5,7 +5,7 @@
* Plugin URI: http://wordpress.org/extend/plugins/jetpack/
* Description: Bring the power of the WordPress.com cloud to your self-hosted WordPress. Jetpack enables you to connect your blog to a WordPress.com account to use the powerful features normally only available to WordPress.com users.
* Author: Automattic
- * Version: 2.2
+ * Version: 2.3.3
* Author URI: http://jetpack.me
* License: GPL2+
* Text Domain: jetpack
@@ -17,4469 +17,51 @@ define( 'JETPACK__API_VERSION', 1 );
define( 'JETPACK__MINIMUM_WP_VERSION', '3.3' );
defined( 'JETPACK_CLIENT__AUTH_LOCATION' ) or define( 'JETPACK_CLIENT__AUTH_LOCATION', 'header' );
defined( 'JETPACK_CLIENT__HTTPS' ) or define( 'JETPACK_CLIENT__HTTPS', 'AUTO' );
-define( 'JETPACK__VERSION', '2.2' );
+define( 'JETPACK__VERSION', '2.3.3' );
define( 'JETPACK__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) or define( 'JETPACK__GLOTPRESS_LOCALES_PATH', JETPACK__PLUGIN_DIR . 'locales.php' );
define( 'JETPACK_MASTER_USER', true );
-/*
-Options:
-jetpack_options (array)
- An array of options.
- @see Jetpack::get_option_names()
-
-jetpack_register (string)
- Temporary verification secrets.
-
-jetpack_activated (int)
- 1: the plugin was activated normally
- 2: the plugin was activated on this site because of a network-wide activation
- 3: the plugin was auto-installed
- 4: the plugin was manually disconnected (but is still installed)
-
-jetpack_active_modules (array)
- Array of active module slugs.
-
-jetpack_do_activate (bool)
- Flag for "activating" the plugin on sites where the activation hook never fired (auto-installs)
-*/
-
-class Jetpack {
- var $xmlrpc_server = null;
-
- var $HTTP_RAW_POST_DATA = null; // copy of $GLOBALS['HTTP_RAW_POST_DATA']
-
- var $plugins_to_deactivate = array(
- 'stats' => array( 'stats/stats.php', 'WordPress.com Stats' ),
- 'shortlinks' => array( 'stats/stats.php', 'WordPress.com Stats' ),
- 'sharedaddy' => array( 'sharedaddy/sharedaddy.php', 'Sharedaddy' ),
- 'twitter-widget' => array( 'wickett-twitter-widget/wickett-twitter-widget.php', 'Wickett Twitter Widget' ),
- 'after-the-deadline' => array( 'after-the-deadline/after-the-deadline.php', 'After The Deadline' ),
- 'contact-form' => array( 'grunion-contact-form/grunion-contact-form.php', 'Grunion Contact Form' ),
- 'custom-css' => array( 'safecss/safecss.php', 'WordPress.com Custom CSS' ),
- );
-
- var $capability_translations = array(
- 'administrator' => 'manage_options',
- 'editor' => 'edit_others_posts',
- 'author' => 'publish_posts',
- 'contributor' => 'edit_posts',
- 'subscriber' => 'read',
- );
-
- /**
- * Message to display in admin_notice
- * @var string
- */
- var $message = '';
-
- /**
- * Error to display in admin_notice
- * @var string
- */
- var $error = '';
-
- /**
- * Modules that need more privacy description.
- * @var string
- */
- var $privacy_checks = '';
-
- /**
- * Stats to record once the page loads
- *
- * @var array
- */
- var $stats = array();
-
- /**
- * Jetpack_Sync object
- */
- var $sync;
-
- /**
- * Verified data for JSON authorization request
- */
- var $json_api_authorization_request = array();
-
- /**
- * Singleton
- * @static
- */
- public static function init() {
- static $instance = false;
-
- if ( !$instance ) {
- load_plugin_textdomain( 'jetpack', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
- $instance = new Jetpack;
-
- $instance->plugin_upgrade();
- }
-
- return $instance;
- }
-
- /**
- * Must never be called statically
- */
- function plugin_upgrade() {
- // Upgrade: 1.1 -> 1.2
- if ( get_option( 'jetpack_id' ) ) {
- // Move individual jetpack options to single array of options
- $options = array();
- foreach ( Jetpack::get_option_names() as $option ) {
- if ( false !== $value = get_option( "jetpack_$option" ) ) {
- $options[$option] = $value;
- }
- }
-
- if ( $options ) {
- Jetpack::update_options( $options );
-
- foreach ( array_keys( $options ) as $option ) {
- delete_option( "jetpack_$option" );
- }
- }
-
- // Add missing version and old_version options
- if ( !$version = Jetpack::get_option( 'version' ) ) {
- $version = $old_version = '1.1:' . time();
- Jetpack::update_options( compact( 'version', 'old_version' ) );
- }
- }
-
- // Upgrade from a single user token to a user_id-indexed array and a master_user ID
- if ( !Jetpack::get_option( 'user_tokens' ) ) {
- if ( $user_token = Jetpack::get_option( 'user_token' ) ) {
- $token_parts = explode( '.', $user_token );
- if ( isset( $token_parts[2] ) ) {
- $master_user = $token_parts[2];
- $user_tokens = array( $master_user => $user_token );
- Jetpack::update_options( compact( 'master_user', 'user_tokens' ) );
- Jetpack::delete_option( 'user_token' );
- } else {
- // @todo: is this even possible?
- trigger_error( sprintf( 'Jetpack::plugin_upgrade found no user_id in user_token "%s"', $user_token ), E_USER_WARNING );
- }
- }
- }
- }
-
- /**
- * Constructor. Initializes WordPress hooks
- */
- function Jetpack() {
- $this->sync = new Jetpack_Sync;
-
- // Modules should do Jetpack_Sync::sync_options( __FILE__, $option, ... ); instead
- // We access the "internal" method here only because the Jetpack object isn't instantiated yet
- $this->sync->options( __FILE__,
- 'home',
- 'siteurl',
- 'blogname',
- 'gmt_offset',
- 'timezone_string'
- );
-
- if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && isset( $_GET['for'] ) && 'jetpack' == $_GET['for'] ) {
- @ini_set( 'display_errors', false ); // Display errors can cause the XML to be not well formed.
-
- require_once dirname( __FILE__ ) . '/class.jetpack-xmlrpc-server.php';
- $this->xmlrpc_server = new Jetpack_XMLRPC_Server();
-
- $this->require_jetpack_authentication();
-
- if ( Jetpack::is_active() ) {
- // Hack to preserve $HTTP_RAW_POST_DATA
- add_filter( 'xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
-
- // The actual API methods.
- add_filter( 'xmlrpc_methods', array( $this->xmlrpc_server, 'xmlrpc_methods' ) );
- } else {
- // The bootstrap API methods.
- add_filter( 'xmlrpc_methods', array( $this->xmlrpc_server, 'bootstrap_xmlrpc_methods' ) );
- }
-
- // Now that no one can authenticate, and we're whitelisting all XML-RPC methods, force enable_xmlrpc on.
- add_filter( 'pre_option_enable_xmlrpc', '__return_true' );
- } elseif ( is_admin() && isset( $_POST['action'] ) && 'jetpack_upload_file' == $_POST['action'] ) {
- $this->require_jetpack_authentication();
- $this->add_remote_request_handlers();
- } else {
- if ( Jetpack::is_active() ) {
- add_action( 'login_form_jetpack_json_api_authorization', array( &$this, 'login_form_json_api_authorization' ) );
- }
- }
-
- add_action( 'jetpack_clean_nonces', array( 'Jetpack', 'clean_nonces' ) );
- if ( !wp_next_scheduled( 'jetpack_clean_nonces' ) ) {
- wp_schedule_event( time(), 'hourly', 'jetpack_clean_nonces' );
- }
-
- add_filter( 'xmlrpc_blog_options', array( $this, 'xmlrpc_options' ) );
-
- add_action( 'admin_menu', array( $this, 'admin_menu' ) );
- add_action( 'admin_init', array( $this, 'admin_init' ) );
- add_action( 'admin_init', array( $this, 'dismiss_jetpack_notice' ) );
-
- add_action( 'wp_ajax_jetpack-check-news-subscription', array( $this, 'check_news_subscription' ) );
- add_action( 'wp_ajax_jetpack-subscribe-to-news', array( $this, 'subscribe_to_news' ) );
-
- add_action( 'wp_loaded', array( $this, 'register_assets' ) );
- add_action( 'wp_enqueue_scripts', array( $this, 'devicepx' ) );
- add_action( 'customize_controls_enqueue_scripts', array( $this, 'devicepx' ) );
- add_action( 'admin_enqueue_scripts', array( $this, 'devicepx' ) );
-
- add_action( 'jetpack_activate_module', array( $this, 'activate_module_actions' ) );
-
- add_action( 'plugins_loaded', array( $this, 'check_open_graph' ), 999 );
- }
-
- function require_jetpack_authentication() {
- // Don't let anyone authenticate
- $_COOKIE = array();
- remove_all_filters( 'authenticate' );
-
- if ( Jetpack::is_active() ) {
- // Allow Jetpack authentication
- add_filter( 'authenticate', array( $this, 'authenticate_jetpack' ), 10, 3 );
- }
- }
-
- /**
- * Register assets for use in various modules and the Jetpack admin page.
- *
- * @uses wp_script_is, wp_register_script, plugins_url
- * @action wp_loaded
- * @return null
- */
- public function register_assets() {
- if ( ! wp_script_is( 'spin', 'registered' ) )
- wp_register_script( 'spin', plugins_url( '_inc/spin.js', __FILE__ ), false, '1.2.4' );
-
- if ( ! wp_script_is( 'jquery.spin', 'registered' ) )
- wp_register_script( 'jquery.spin', plugins_url( '_inc/jquery.spin.js', __FILE__ ) , array( 'jquery', 'spin' ) );
-
- if ( ! wp_script_is( 'jetpack-gallery-settings', 'registered' ) )
- wp_register_script( 'jetpack-gallery-settings', plugins_url( '_inc/gallery-settings.js', __FILE__ ), array( 'media-views' ), '20121225' );
- }
-
- /**
- * Device Pixels support
- * This improves the resolution of gravatars and wordpress.com uploads on hi-res and zoomed browsers.
- */
- function devicepx() {
- wp_enqueue_script( 'devicepx', ( is_ssl() ? 'https' : 'http' ) . '://s0.wp.com/wp-content/js/devicepx-jetpack.js', array(), gmdate('oW'), true );
- }
-
- /**
- * Is Jetpack active?
- */
- public static function is_active() {
- return (bool) Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
- }
-
- /**
- * Is a given user (or the current user if none is specified) linked to a WordPress.com user?
- */
- public static function is_user_connected( $user_id = false ) {
- $user_id = false === $user_id ? get_current_user_id() : absint( $user_id );
- if ( !$user_id ) {
- return false;
- }
- return (bool) Jetpack_Data::get_access_token( $user_id );
- }
-
- function current_user_is_connection_owner() {
- $user_token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
- return $user_token && is_object( $user_token ) && isset( $user_token->external_user_id ) && get_current_user_id() === $user_token->external_user_id;
- }
-
- /**
- * Synchronize connected user role changes
- */
- function user_role_change( $user_id ) {
- if ( Jetpack::is_active() && Jetpack::is_user_connected( $user_id ) ) {
-
- $current_user_id = get_current_user_id();
- wp_set_current_user( $user_id );
- $role = $this->translate_current_user_to_role();
- $signed_role = $this->sign_role( $role );
- wp_set_current_user( $current_user_id );
-
- $master_token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
- $master_user_id = absint( $master_token->external_user_id );
-
- if ( !$master_user_id )
- return; // this shouldn't happen
-
- Jetpack::xmlrpc_async_call( 'jetpack.updateRole', $user_id, $signed_role );
- //@todo retry on failure
-
- //try to choose a new master if we're demoting the current one
- if ( $user_id == $master_user_id && 'administrator' != $role ) {
- $query = new WP_User_Query( array(
- 'fields' => array( 'id' ),
- 'role' => 'administrator',
- 'orderby' => 'id',
- 'exclude' => array( $master_user_id ),
- )
- );
- $new_master = false;
- foreach ( $query->results as $result ) {
- $uid = absint( $result->id );
- if ( $uid && Jetpack::is_user_connected( $uid ) ) {
- $new_master = $uid;
- break;
- }
- }
-
- if ( $new_master ) {
- Jetpack::update_option( 'master_user', $new_master );
- }
- // else disconnect..?
- }
- }
- }
-
- /**
- * Loads the currently active modules.
- */
- public static function load_modules() {
- if ( !Jetpack::is_active() ) {
- return;
- }
-
- $version = Jetpack::get_option( 'version' );
- if ( !$version ) {
- $version = $old_version = JETPACK__VERSION . ':' . time();
- Jetpack::update_options( compact( 'version', 'old_version' ) );
- }
- list( $version ) = explode( ':', $version );
-
- $modules = array_filter( Jetpack::get_active_modules(), array( 'Jetpack', 'is_module' ) );
-
- // Don't load modules that have had "Major" changes since the stored version until they have been deactivated/reactivated through the lint check.
- if ( version_compare( $version, JETPACK__VERSION, '<' ) ) {
- $updated_modules = array();
- foreach ( $modules as $module ) {
- $module_data = Jetpack::get_module( $module );
- if ( !isset( $module_data['changed'] ) ) {
- continue;
- }
-
- if ( version_compare( $module_data['changed'], $version, '<=' ) ) {
- continue;
- }
-
- $updated_modules[] = $module;
- }
-
- $modules = array_diff( $modules, $updated_modules );
- }
-
- foreach ( $modules as $module ) {
- if ( did_action( 'jetpack_module_loaded_' . $module ) ) {
- continue;
- }
- require Jetpack::get_module_path( $module );
- do_action( 'jetpack_module_loaded_' . $module );
- }
-
- do_action( 'jetpack_modules_loaded' );
-
- // Load module-specific code that is needed even when a module isn't active. Loaded here because code contained therein may need actions such as setup_theme.
- require_once( dirname( __FILE__ ) . '/modules/module-extras.php' );
- }
-
- /**
- * Check if Jetpack's Open Graph tags should be used.
- * If certain plugins are active, Jetpack's og tags are suppressed.
- *
- * @uses Jetpack::get_active_modules, add_filter, get_option, apply_filters
- * @action plugins_loaded
- * @return null
- */
- public function check_open_graph() {
- if ( in_array( 'publicize', Jetpack::get_active_modules() ) || in_array( 'sharedaddy', Jetpack::get_active_modules() ) )
- add_filter( 'jetpack_enable_open_graph', '__return_true', 0 );
-
- $active_plugins = get_option( 'active_plugins', array() );
-
- $conflicting_plugins = array(
- 'facebook/facebook.php', // Official Facebook plugin
- 'wordpress-seo/wp-seo.php', // WordPress SEO by Yoast
- 'add-link-to-facebook/add-link-to-facebook.php', // Add Link to Facebook
- 'facebook-awd/AWD_facebook.php', // Facebook AWD All in one
- 'header-footer/plugin.php', // Header and Footer
- 'nextgen-facebook/nextgen-facebook.php', // NextGEN Facebook OG
- 'seo-facebook-comments/seofacebook.php', // SEO Facebook Comments
- 'seo-ultimate/seo-ultimate.php', // SEO Ultimate
- 'sexybookmarks/sexy-bookmarks.php', // Shareaholic
- 'shareaholic/sexy-bookmarks.php', // Shareaholic
- 'social-discussions/social-discussions.php', // Social Discussions
- 'social-networks-auto-poster-facebook-twitter-g/NextScripts_SNAP.php', // NextScripts SNAP
- 'wordbooker/wordbooker.php', // Wordbooker
- 'socialize/socialize.php', // Socialize
- 'simple-facebook-connect/sfc.php', // Simple Facebook Connect
- 'social-sharing-toolkit/social_sharing_toolkit.php', // Social Sharing Toolkit
- 'wp-facebook-open-graph-protocol/wp-facebook-ogp.php', // WP Facebook Open Graph protocol
- 'opengraph/opengraph.php', // Open Graph
- 'sharepress/sharepress.php', // SharePress
- );
-
- foreach ( $conflicting_plugins as $plugin ) {
- if ( in_array( $plugin, $active_plugins ) ) {
- add_filter( 'jetpack_enable_open_graph', '__return_false', 99 );
- break;
- }
- }
-
- if ( apply_filters( 'jetpack_enable_open_graph', false ) )
- require_once dirname( __FILE__ ) . '/functions.opengraph.php';
- }
-
-/* Jetpack Options API */
-
- public static function get_option_names( $type = 'compact' ) {
- switch ( $type ) {
- case 'non-compact' :
- case 'non_compact' :
- return array(
- 'register',
- 'activated',
- 'active_modules',
- 'do_activate',
- 'publicize',
- 'widget_twitter',
- );
- }
-
- return array(
- 'id', // (int) The Client ID/WP.com Blog ID of this site.
- 'blog_token', // (string) The Client Secret/Blog Token of this site.
- 'user_token', // (string) The User Token of this site. (deprecated)
- 'publicize_connections', // (array) An array of Publicize connections from WordPress.com
- 'master_user', // (int) The local User ID of the user who connected this site to jetpack.wordpress.com.
- 'user_tokens', // (array) User Tokens for each user of this site who has connected to jetpack.wordpress.com.
- 'version', // (string) Used during upgrade procedure to auto-activate new modules. version:time
- 'old_version', // (string) Used to determine which modules are the most recently added. previous_version:time
- 'fallback_no_verify_ssl_certs', // (int) Flag for determining if this host must skip SSL Certificate verification due to misconfigured SSL.
- 'time_diff', // (int) Offset between Jetpack server's clocks and this server's clocks. Jetpack Server Time = time() + (int) Jetpack::get_option( 'time_diff' )
- 'public', // (int|bool) If we think this site is public or not (1, 0), false if we haven't yet tried to figure it out.
- );
- }
-
- /**
- * Returns the requested option. Looks in jetpack_options or jetpack_$name as appropriate.
- *
- * @param string $name Option name
- * @param mixed $default (optional)
- */
- public static function get_option( $name, $default = false ) {
- if ( in_array( $name, Jetpack::get_option_names( 'non_compact' ) ) ) {
- return get_option( "jetpack_$name" );
- } else if ( !in_array( $name, Jetpack::get_option_names() ) ) {
- trigger_error( sprintf( 'Invalid Jetpack option name: %s', $name ), E_USER_WARNING );
- return false;
- }
-
- $options = get_option( 'jetpack_options' );
- if ( is_array( $options ) && isset( $options[$name] ) ) {
- return $options[$name];
- }
-
- return $default;
- }
-
- /**
- * Stores two secrets and a timestamp so WordPress.com can make a request back and verify an action
- * Does some extra verification so urls (such as those to public-api, register, etc) cant just be crafted
- * $name must be a registered option name.
- */
- public static function create_nonce( $name ) {
- $secret = wp_generate_password( 32, false ) . ':' . wp_generate_password( 32, false ) . ':' . ( time() + 600 );
-
- Jetpack::update_option( $name, $secret );
- @list( $secret_1, $secret_2, $eol ) = explode( ':', Jetpack::get_option( $name ) );
- if ( empty( $secret_1 ) || empty( $secret_2 ) || $eol < time() )
- return new Jetpack_Error( 'missing_secrets' );
-
- return array(
- 'secret_1' => $secret_1,
- 'secret_2' => $secret_2,
- 'eol' => $eol,
- );
- }
-
- /**
- * Updates the single given option. Updates jetpack_options or jetpack_$name as appropriate.
- *
- * @param string $name Option name
- * @param mixed $value Option value
- */
- public static function update_option( $name, $value ) {
- if ( in_array( $name, Jetpack::get_option_names( 'non_compact' ) ) ) {
- return update_option( "jetpack_$name", $value );
- } else if ( !in_array( $name, Jetpack::get_option_names() ) ) {
- trigger_error( sprintf( 'Invalid Jetpack option name: %s', $name ), E_USER_WARNING );
- return false;
- }
-
- $options = get_option( 'jetpack_options' );
- if ( !is_array( $options ) ) {
- $options = array();
- }
-
- $options[$name] = $value;
-
- return update_option( 'jetpack_options', $options );
- }
-
- /**
- * Updates the multiple given options. Updates jetpack_options and/or jetpack_$name as appropriate.
- *
- * @param array $array array( option name => option value, ... )
- */
- public static function update_options( $array ) {
- $names = array_keys( $array );
-
- foreach ( array_diff( $names, Jetpack::get_option_names(), Jetpack::get_option_names( 'non_compact' ) ) as $unknown_name ) {
- trigger_error( sprintf( 'Invalid Jetpack option name: %s', $unknown_name ), E_USER_WARNING );
- unset( $array[$unknown_name] );
- }
-
- foreach ( array_intersect( $names, Jetpack::get_option_names( 'non_compact' ) ) as $name ) {
- update_option( "jetpack_$name", $array[$name] );
- unset( $array[$name] );
- }
-
- $options = get_option( 'jetpack_options' );
- if ( !is_array( $options ) ) {
- $options = array();
- }
-
- return update_option( 'jetpack_options', array_merge( $options, $array ) );
- }
-
- /**
- * Deletes the given option. May be passed multiple option names as an array.
- * Updates jetpack_options and/or deletes jetpack_$name as appropriate.
- *
- * @param string|array $names
- */
- public static function delete_option( $names ) {
- $names = (array) $names;
-
- foreach ( array_diff( $names, Jetpack::get_option_names(), Jetpack::get_option_names( 'non_compact' ) ) as $unknown_name ) {
- trigger_error( sprintf( 'Invalid Jetpack option name: %s', $unknown_name ), E_USER_WARNING );
- }
-
- foreach ( array_intersect( $names, Jetpack::get_option_names( 'non_compact' ) ) as $name ) {
- delete_option( "jetpack_$name" );
- }
-
- $options = get_option( 'jetpack_options' );
- if ( !is_array( $options ) ) {
- $options = array();
- }
-
- $to_delete = array_intersect( $names, Jetpack::get_option_names(), array_keys( $options ) );
- if ( $to_delete ) {
- foreach ( $to_delete as $name ) {
- unset( $options[$name] );
- }
-
- return update_option( 'jetpack_options', $options );
- }
-
- return true;
- }
-
- /**
- * Enters a user token into the user_tokens option
- *
- * @param int $user_id
- * @param string $token
- * return bool
- */
- public static function update_user_token( $user_id, $token, $is_master_user ) {
- // not designed for concurrent updates
- $user_tokens = Jetpack::get_option( 'user_tokens' );
- if ( ! is_array( $user_tokens ) )
- $user_tokens = array();
- $user_tokens[$user_id] = $token;
- if ( $is_master_user ) {
- $master_user = $user_id;
- $options = compact('user_tokens', 'master_user');
- } else {
- $options = compact('user_tokens');
- }
- return Jetpack::update_options( $options );
- }
-
- /**
- * Returns an array of all PHP files in the specified absolute path.
- * Equivalent to glob( "$absolute_path/*.php" ).
- *
- * @param string $absolute_path The absolute path of the directory to search.
- * @return array Array of absolute paths to the PHP files.
- */
- public static function glob_php( $absolute_path ) {
- $absolute_path = untrailingslashit( $absolute_path );
- $files = array();
- if ( !$dir = @opendir( $absolute_path ) ) {
- return $files;
- }
-
- while ( false !== $file = readdir( $dir ) ) {
- if ( '.' == substr( $file, 0, 1 ) || '.php' != substr( $file, -4 ) ) {
- continue;
- }
-
- $file = "$absolute_path/$file";
-
- if ( !is_file( $file ) ) {
- continue;
- }
-
- $files[] = $file;
- }
-
- closedir( $dir );
-
- return $files;
- }
-
- public function activate_new_modules() {
- if ( ! Jetpack::is_active() ) {
- return;
- }
-
- $jetpack_old_version = Jetpack::get_option( 'version' ); // [sic]
- if ( !$jetpack_old_version ) {
- $jetpack_old_version = $version = $old_version = '1.1:' . time();
- Jetpack::update_options( compact( 'version', 'old_version' ) );
- }
-
- list( $jetpack_version ) = explode( ':', $jetpack_old_version ); // [sic]
-
- if ( version_compare( JETPACK__VERSION, $jetpack_version, '<=' ) ) {
- return;
- }
-
- $active_modules = Jetpack::get_active_modules();
- $reactivate_modules = array();
- foreach ( $active_modules as $active_module ) {
- $module = Jetpack::get_module( $active_module );
- if ( !isset( $module['changed'] ) ) {
- continue;
- }
-
- if ( version_compare( $module['changed'], $jetpack_version, '<=' ) ) {
- continue;
- }
-
- $reactivate_modules[] = $active_module;
- Jetpack::deactivate_module( $active_module );
- }
-
- if ( version_compare( $jetpack_version, '1.9.2', '<' ) && version_compare( '1.9-something', JETPACK__VERSION, '<' ) ) {
- add_action( 'jetpack_activate_default_modules', array( $this->sync, 'sync_all_registered_options' ), 1000 );
- }
-
- Jetpack::update_options( array(
- 'version' => JETPACK__VERSION . ':' . time(),
- 'old_version' => $jetpack_old_version,
- ) );
-
- Jetpack::state( 'message', 'modules_activated' );
- Jetpack::activate_default_modules( $jetpack_version, JETPACK__VERSION, $reactivate_modules );
- wp_safe_redirect( Jetpack::admin_url() );
- exit;
- }
-
- /**
- * List available Jetpack modules. Simply lists .php files in /modules/.
- * Make sure to tuck away module "library" files in a sub-directory.
- */
- public static function get_available_modules( $min_version = false, $max_version = false ) {
- static $modules = null;
-
- if ( !isset( $modules ) ) {
- $files = Jetpack::glob_php( dirname( __FILE__ ) . '/modules' );
-
- $modules = array();
-
- foreach ( $files as $file ) {
- if ( !$headers = Jetpack::get_module( $file ) ) {
- continue;
- }
-
- $modules[ Jetpack::get_module_slug( $file ) ] = $headers['introduced'];
- }
- }
-
- if ( !$min_version && !$max_version ) {
- return array_keys( $modules );
- }
-
- $r = array();
- foreach ( $modules as $slug => $introduced ) {
- if ( $min_version && version_compare( $min_version, $introduced, '>=' ) ) {
- continue;
- }
-
- if ( $max_version && version_compare( $max_version, $introduced, '<' ) ) {
- continue;
- }
-
- $r[] = $slug;
- }
-
- return $r;
- }
-
- /**
- * Default modules loaded on activation.
- */
- public static function get_default_modules( $min_version = false, $max_version = false ) {
- $return = array();
-
- foreach ( Jetpack::get_available_modules( $min_version, $max_version ) as $module ) {
- // Add special cases here for modules to avoid auto-activation
- switch ( $module ) {
-
- // These modules are default off: they change things blog-side
- case 'comments' :
- case 'carousel' :
- case 'minileven':
- case 'infinite-scroll' :
- case 'photon' :
- case 'tiled-gallery' :
- case 'likes' :
- break;
-
- // These modules are default off if we think the site is a private one
- case 'enhanced-distribution' :
- case 'json-api' :
- if ( !Jetpack::get_option( 'public' ) ) {
- break;
- }
- // else no break
- // The rest are default on
- default :
- $return[] = $module;
- }
- }
-
- return $return;
- }
-
- /**
- * Extract a module's slug from its full path.
- */
- public static function get_module_slug( $file ) {
- return str_replace( '.php', '', basename( $file ) );
- }
-
- /**
- * Generate a module's path from its slug.
- */
- public static function get_module_path( $slug ) {
- return dirname( __FILE__ ) . "/modules/$slug.php";
- }
-
- /**
- * Load module data from module file. Headers differ from WordPress
- * plugin headers to avoid them being identified as standalone
- * plugins on the WordPress plugins page.
- */
- public static function get_module( $module ) {
- $headers = array(
- 'name' => 'Module Name',
- 'description' => 'Module Description',
- 'sort' => 'Sort Order',
- 'introduced' => 'First Introduced',
- 'changed' => 'Major Changes In',
- 'deactivate' => 'Deactivate',
- 'free' => 'Free',
- );
-
- $file = Jetpack::get_module_path( Jetpack::get_module_slug( $module ) );
- if ( !file_exists( $file ) )
- return false;
-
- $mod = get_file_data( $file, $headers );
- if ( empty( $mod['name'] ) )
- return false;
-
- $mod['name'] = translate( $mod['name'], 'jetpack' );
- $mod['description'] = translate( $mod['description'], 'jetpack' );
- if ( empty( $mod['sort'] ) )
- $mod['sort'] = 10;
- $mod['deactivate'] = empty( $mod['deactivate'] );
- $mod['free'] = empty( $mod['free'] );
- return $mod;
- }
-
- /**
- * Get a list of activated modules as an array of module slugs.
- */
- public static function get_active_modules() {
- $active = Jetpack::get_option( 'active_modules' );
- if ( !is_array( $active ) )
- $active = array();
- if ( is_admin() ) {
- $active[] = 'vaultpress';
- } else {
- $active = array_diff( $active, array( 'vaultpress' ) );
- }
- return array_unique( $active );
- }
-
- public static function is_module( $module ) {
- return !empty( $module ) && !validate_file( $module, Jetpack::get_available_modules() );
- }
-
- /**
- * Catches PHP errors. Must be used in conjunction with output buffering.
- *
- * @param bool $catch True to start catching, False to stop.
- *
- * @static
- */
- public static function catch_errors( $catch ) {
- static $display_errors, $error_reporting;
-
- if ( $catch ) {
- $display_errors = @ini_set( 'display_errors', 1 );
- $error_reporting = @error_reporting( E_ALL );
- add_action( 'shutdown', array( 'Jetpack', 'catch_errors_on_shutdown' ), 0 );
- } else {
- @ini_set( 'display_errors', $display_errors );
- @error_reporting( $error_reporting );
- remove_action( 'shutdown', array( 'Jetpack', 'catch_errors_on_shutdown' ), 1 );
- }
- }
-
- /**
- * Saves any generated PHP errors in ::state( 'php_errors', {errors} )
- */
- public static function catch_errors_on_shutdown() {
- Jetpack::state( 'php_errors', ob_get_clean() );
- }
-
- public static function activate_default_modules( $min_version = false, $max_version = false, $other_modules = array() ) {
- $jetpack = Jetpack::init();
-
- $modules = Jetpack::get_default_modules( $min_version, $max_version );
- $modules = array_merge( $other_modules, $modules );
-
- // Look for standalone plugins and disable if active.
-
- $to_deactivate = array();
- foreach ( $modules as $module ) {
- if ( isset( $jetpack->plugins_to_deactivate[$module] ) ) {
- $to_deactivate[$module] = $jetpack->plugins_to_deactivate[$module];
- }
- }
-
- $deactivated = array();
- foreach ( $to_deactivate as $module => $deactivate_me ) {
- list( $probable_file, $probable_title ) = $deactivate_me;
- if ( Jetpack_Client_Server::deactivate_plugin( $probable_file, $probable_title ) ) {
- $deactivated[] = $module;
- }
- }
-
- if ( $deactivated ) {
- Jetpack::state( 'deactivated_plugins', join( ',', $deactivated ) );
-
- $url = add_query_arg( array(
- 'action' => 'activate_default_modules',
- '_wpnonce' => wp_create_nonce( 'activate_default_modules' ),
- ), add_query_arg( compact( 'min_version', 'max_version', 'other_modules' ), Jetpack::admin_url() ) );
- wp_safe_redirect( $url );
- exit;
- }
-
- do_action( 'jetpack_before_activate_default_modules', $min_version, $max_version, $other_modules );
-
- // Check each module for fatal errors, a la wp-admin/plugins.php::activate before activating
- $redirect = menu_page_url( 'jetpack', false );
- Jetpack::restate();
- Jetpack::catch_errors( true );
- foreach ( $modules as $module ) {
- $active = Jetpack::get_active_modules();
- if ( in_array( $module, $active ) ) {
- $module_info = Jetpack::get_module( $module );
- if ( !$module_info['deactivate'] ) {
- $state = in_array( $module, $other_modules ) ? 'reactivated_modules' : 'activated_modules';
- if ( $active_state = Jetpack::state( $state ) ) {
- $active_state = explode( ',', $active_state );
- } else {
- $active_state = array();
- }
- $active_state[] = $module;
- Jetpack::state( $state, implode( ',', $active_state ) );
- }
- continue;
- }
-
- $file = Jetpack::get_module_path( $module );
- if ( !file_exists( $file ) ) {
- continue;
- }
-
- // we'll override this later if the plugin can be included without fatal error
- wp_safe_redirect( Jetpack::admin_url() );
- Jetpack::state( 'error', 'module_activation_failed' );
- Jetpack::state( 'module', $module );
- ob_start();
- require $file;
- do_action( 'jetpack_activate_module', $module );
- $active[] = $module;
- $state = in_array( $module, $other_modules ) ? 'reactivated_modules' : 'activated_modules';
- if ( $active_state = Jetpack::state( $state ) ) {
- $active_state = explode( ',', $active_state );
- } else {
- $active_state = array();
- }
- $active_state[] = $module;
- Jetpack::state( $state, implode( ',', $active_state ) );
- Jetpack::update_option( 'active_modules', array_unique( $active ) );
- ob_end_clean();
- }
- Jetpack::state( 'error', false );
- Jetpack::state( 'module', false );
- Jetpack::catch_errors( false );
- do_action( 'jetpack_activate_default_modules', $min_version, $max_version, $other_modules );
- }
-
- public static function activate_module( $module ) {
- $jetpack = Jetpack::init();
-
- if ( !Jetpack::is_active() )
- return false;
-
- if ( !strlen( $module ) )
- return false;
-
- if ( !Jetpack::is_module( $module ) )
- return false;
-
- // If it's already active, then don't do it again
- $active = Jetpack::get_active_modules();
- foreach ( $active as $act ) {
- if ( $act == $module )
- return true;
- }
-
- // Check and see if the old plugin is active
- if ( isset( $jetpack->plugins_to_deactivate[$module] ) ) {
- // Deactivate the old plugin
- if ( Jetpack_Client_Server::deactivate_plugin( $jetpack->plugins_to_deactivate[$module][0], $jetpack->plugins_to_deactivate[$module][1] ) ) {
- // If we deactivated the old plugin, remembere that with ::state() and redirect back to this page to activate the module
- // We can't activate the module on this page load since the newly deactivated old plugin is still loaded on this page load.
- Jetpack::state( 'deactivated_plugins', $module );
- wp_safe_redirect( add_query_arg( 'jetpack_restate', 1 ) );
- exit;
- }
- }
-
- // Check the file for fatal errors, a la wp-admin/plugins.php::activate
- Jetpack::state( 'module', $module );
- Jetpack::state( 'error', 'module_activation_failed' ); // we'll override this later if the plugin can be included without fatal error
- wp_safe_redirect( Jetpack::admin_url() );
-
- Jetpack::catch_errors( true );
- ob_start();
- require Jetpack::get_module_path( $module );
- do_action( 'jetpack_activate_module', $module );
- $active[] = $module;
- Jetpack::update_option( 'active_modules', array_unique( $active ) );
- Jetpack::state( 'error', false ); // the override
- Jetpack::state( 'message', 'module_activated' );
- Jetpack::state( 'module', $module );
- ob_end_clean();
- Jetpack::catch_errors( false );
- exit;
- }
-
- function activate_module_actions( $module ) {
- do_action( "jetpack_activate_module_$module" );
-
- $this->sync->sync_all_module_options( $module );
- }
-
- public static function deactivate_module( $module ) {
- $active = Jetpack::get_active_modules();
- $new = array();
- foreach ( $active as $check ) {
- if ( !empty( $check ) && $module != $check )
- $new[] = $check;
- }
-
- do_action( "jetpack_deactivate_module_$module" );
- return Jetpack::update_option( 'active_modules', array_unique( $new ) );
- }
-
- public static function enable_module_configurable( $module ) {
- $module = Jetpack::get_module_slug( $module );
- add_filter( 'jetpack_module_configurable_' . $module, '__return_true' );
- }
-
- public static function module_configuration_url( $module ) {
- $module = Jetpack::get_module_slug( $module );
- return Jetpack::admin_url( array( 'configure' => $module ) );
- }
-
- public static function module_configuration_load( $module, $method ) {
- $module = Jetpack::get_module_slug( $module );
- add_action( 'jetpack_module_configuration_load_' . $module, $method );
- }
-
- public static function module_configuration_head( $module, $method ) {
- $module = Jetpack::get_module_slug( $module );
- add_action( 'jetpack_module_configuration_head_' . $module, $method );
- }
-
- public static function module_configuration_screen( $module, $method ) {
- $module = Jetpack::get_module_slug( $module );
- add_action( 'jetpack_module_configuration_screen_' . $module, $method );
- }
-
-/* Installation */
-
- public static function bail_on_activation( $message, $deactivate = true ) {
-?>
-<!doctype html>
-<html>
-<head>
-<meta charset="<?php bloginfo( 'charset' ); ?>">
-<style>
-* {
- text-align: center;
- margin: 0;
- padding: 0;
- font-family: "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;
-}
-p {
- margin-top: 1em;
- font-size: 18px;
-}
-</style>
-<body>
-<p><?php echo esc_html( $message ); ?></p>
-</body>
-</html>
-<?php
- if ( $deactivate ) {
- $plugins = get_option( 'active_plugins' );
- $jetpack = plugin_basename( __FILE__ );
- $update = false;
- foreach ( $plugins as $i => $plugin ) {
- if ( $plugin === $jetpack ) {
- $plugins[$i] = false;
- $update = true;
- }
- }
-
- if ( $update ) {
- update_option( 'active_plugins', array_filter( $plugins ) );
- }
- }
- exit;
- }
-
- /**
- * Attached to activate_{ plugin_basename( __FILES__ ) } by register_activation_hook()
- * @static
- */
- public static function plugin_activation( $network_wide ) {
- Jetpack::update_option( 'activated', 1 );
-
- if ( version_compare( $GLOBALS['wp_version'], JETPACK__MINIMUM_WP_VERSION, '<' ) ) {
- Jetpack::bail_on_activation( sprintf( __( 'Jetpack requires WordPress version %s or later.', 'jetpack' ), JETPACK__MINIMUM_WP_VERSION ) );
- }
-
- if ( $network_wide )
- Jetpack::state( 'network_nag', true );
-
- Jetpack::plugin_initialize();
- }
-
- /**
- * Sets the internal version number and activation state.
- * @static
- */
- public static function plugin_initialize() {
- if ( !Jetpack::get_option( 'activated' ) ) {
- Jetpack::update_option( 'activated', 2 );
- }
-
- if ( !Jetpack::get_option( 'version' ) ) {
- $version = $old_version = JETPACK__VERSION . ':' . time();
- Jetpack::update_options( compact( 'version', 'old_version' ) );
- }
-
- Jetpack::load_modules();
-
- Jetpack::delete_option( 'do_activate' );
- }
-
- /**
- * Removes all connection options
- * @static
- */
- public static function plugin_deactivation( $network_wide ) {
- Jetpack::disconnect( false );
- }
-
- /**
- * Disconnects from the Jetpack servers.
- * Forgets all connection details and tells the Jetpack servers to do the same.
- * @static
- */
- public static function disconnect( $update_activated_state = true ) {
- wp_clear_scheduled_hook( 'jetpack_clean_nonces' );
- Jetpack::clean_nonces( true );
-
- Jetpack::load_xml_rpc_client();
- $xml = new Jetpack_IXR_Client();
- $xml->query( 'jetpack.deregister' );
-
- Jetpack::delete_option( array(
- 'register',
- 'blog_token',
- 'user_token',
- 'user_tokens',
- 'master_user',
- 'time_diff',
- 'fallback_no_verify_ssl_certs',
- ) );
-
- if ( $update_activated_state ) {
- Jetpack::update_option( 'activated', 4 );
- }
- }
-
- /**
- * Unlinks the current user from the linked WordPress.com user
- */
- function unlink_user() {
- if ( !$tokens = Jetpack::get_option( 'user_tokens' ) )
- return false;
-
- $user_id = get_current_user_id();
-
- if ( Jetpack::get_option( 'master_user' ) == $user_id )
- return false;
-
- if ( !isset( $tokens[$user_id] ) )
- return false;
-
- Jetpack::load_xml_rpc_client();
- $xml = new Jetpack_IXR_Client( compact( 'user_id' ) );
- $xml->query( 'jetpack.unlink_user', $user_id );
-
- unset( $tokens[$user_id] );
-
- Jetpack::update_option( 'user_tokens', $tokens );
-
- return true;
- }
-
- /**
- * Attempts Jetpack registration. If it fail, a state flag is set: @see ::admin_page_load()
- */
- public static function try_registration() {
- $result = Jetpack::register();
-
- // If there was an error with registration and the site was not registered, record this so we can show a message.
- if ( !$result || is_wp_error( $result ) ) {
- return $result;
- } else {
- return true;
- }
- }
-
-/* Admin Pages */
-
- function admin_init() {
- // If the plugin is not connected, display a connect message.
- if (
- // the plugin was auto-activated and needs its candy
- Jetpack::get_option( 'do_activate' )
- ||
- // the plugin is active, but was never activated. Probably came from a site-wide network activation
- !Jetpack::get_option( 'activated' )
- ) {
- Jetpack::plugin_initialize();
- }
-
- if ( !Jetpack::is_active() ) {
- if ( 4 != Jetpack::get_option( 'activated' ) ) {
- // Show connect notice on dashboard and plugins pages
- add_action( 'load-index.php', array( $this, 'prepare_connect_notice' ) );
- add_action( 'load-plugins.php', array( $this, 'prepare_connect_notice' ) );
- }
- } elseif ( false === Jetpack::get_option( 'fallback_no_verify_ssl_certs' ) ) {
- // Upgrade: 1.1 -> 1.1.1
- // Check and see if host can verify the Jetpack servers' SSL certificate
- $args = array();
- Jetpack_Client::_wp_remote_request(
- Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'test' ), $args ),
- $args,
- true
- );
- }
-
- add_action( 'load-plugins.php', array( $this, 'intercept_plugin_error_scrape_init' ) );
- add_action( 'admin_head', array( $this, 'admin_menu_css' ) );
- add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
-
- add_action( 'wp_ajax_jetpack_debug', array( $this, 'ajax_debug' ) );
-
- if ( Jetpack::is_active() ) {
- // Artificially throw errors in certain whitelisted cases during plugin activation
- add_action( 'activate_plugin', array( $this, 'throw_error_on_activate_plugin' ) );
-
- // Kick off synchronization of user role when it changes
- add_action( 'set_user_role', array( $this, 'user_role_change' ) );
-
- // Add retina images hotfix to admin
- global $wp_db_version;
- if ( $wp_db_version > 19470 ) {
- // WP 3.4.x
- // TODO will need to add && $wp_db_version < xxxxx when 3.5 comes out.
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_retina_scripts' ) );
- // /wp-admin/customize.php omits the action above.
- add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_retina_scripts' ) );
- }
- }
- }
-
- function prepare_connect_notice() {
- add_action( 'admin_print_styles', array( $this, 'admin_styles' ) );
-
- add_action( 'admin_notices', array( $this, 'admin_connect_notice' ) );
-
- if ( Jetpack::state( 'network_nag' ) )
- add_action( 'network_admin_notices', array( $this, 'network_connect_notice' ) );
- }
-
- /**
- * Sometimes a plugin can activate without causing errors, but it will cause errors on the next page load.
- * This function artificially throws errors for such cases (whitelisted).
- *
- * @param string $plugin The activated plugin.
- */
- function throw_error_on_activate_plugin( $plugin ) {
- $active_modules = Jetpack::get_active_modules();
-
- // The Shortlinks module and the Stats plugin conflict, but won't cause errors on activation because of some function_exists() checks.
- if ( function_exists( 'stats_get_api_key' ) && in_array( 'shortlinks', $active_modules ) ) {
- $throw = false;
-
- // Try and make sure it really was the stats plugin
- if ( !class_exists( 'ReflectionFunction' ) ) {
- if ( 'stats.php' == basename( $plugin ) ) {
- $throw = true;
- }
- } else {
- $reflection = new ReflectionFunction( 'stats_get_api_key' );
- if ( basename( $plugin ) == basename( $reflection->getFileName() ) ) {
- $throw = true;
- }
- }
-
- if ( $throw ) {
- trigger_error( sprintf( __( 'Jetpack contains the most recent version of the old &#8220;%1$s&#8221; plugin.', 'jetpack' ), 'WordPress.com Stats' ), E_USER_ERROR );
- }
- }
- }
-
- function intercept_plugin_error_scrape_init() {
- add_action( 'check_admin_referer', array( $this, 'intercept_plugin_error_scrape' ), 10, 2 );
- }
-
- function intercept_plugin_error_scrape( $action, $result ) {
- if ( !$result ) {
- return;
- }
-
- foreach ( $this->plugins_to_deactivate as $module => $deactivate_me ) {
- if ( "plugin-activation-error_{$deactivate_me[0]}" == $action ) {
- Jetpack::bail_on_activation( sprintf( __( 'Jetpack contains the most recent version of the old &#8220;%1$s&#8221; plugin.', 'jetpack' ), $deactivate_me[1] ), false );
- }
- }
- }
-
- function admin_menu() {
- list( $jetpack_version ) = explode( ':', Jetpack::get_option( 'version' ) );
- if (
- $jetpack_version
- &&
- $jetpack_version != JETPACK__VERSION
- &&
- ( $new_modules = Jetpack::get_default_modules( $jetpack_version, JETPACK__VERSION ) )
- &&
- is_array( $new_modules )
- &&
- ( $new_modules_count = count( $new_modules ) )
- &&
- Jetpack::is_active()
- ) {
- $new_modules_count_i18n = number_format_i18n( $new_modules_count );
- $span_title = esc_attr( sprintf( _n( 'One New Jetpack Module', '%s New Jetpack Modules', $new_modules_count, 'jetpack' ), $new_modules_count_i18n ) );
- $title = sprintf( 'Jetpack %s', "<span class='update-plugins count-{$new_modules_count}' title='$span_title'><span class='update-count'>$new_modules_count_i18n</span></span>" );
- } else {
- $title = __( 'Jetpack', 'jetpack' );
- }
-
- $hook = add_menu_page( 'Jetpack', $title, 'read', 'jetpack', array( $this, 'admin_page' ), 'div' );
-
- add_action( "load-$hook", array( $this, 'admin_page_load' ) );
-
- if ( version_compare( $GLOBALS['wp_version'], '3.3', '<' ) ) {
- if ( isset( $_GET['page'] ) && 'jetpack' == $_GET['page'] ) {
- add_contextual_help( $hook, $this->jetpack_help() );
- }
- } else {
- add_action( "load-$hook", array( $this, 'admin_help' ) );
- }
- add_action( "admin_head-$hook", array( $this, 'admin_head' ) );
- add_filter( 'custom_menu_order', array( $this, 'admin_menu_order' ) );
- add_filter( 'menu_order', array( $this, 'jetpack_menu_order' ) );
-
- add_action( "admin_print_styles-$hook", array( $this, 'admin_styles' ) );
-
- add_action( "admin_print_scripts-$hook", array( $this, 'admin_scripts' ) );
-
- do_action( 'jetpack_admin_menu' );
- }
-
- function add_remote_request_handlers() {
- add_action( 'wp_ajax_nopriv_jetpack_upload_file', array( $this, 'remote_request_handlers' ) );
- }
-
- function remote_request_handlers() {
- switch ( current_filter() ) {
- case 'wp_ajax_nopriv_jetpack_upload_file' :
- $response = $this->upload_handler();
- break;
- default :
- $response = new Jetpack_Error( 'unknown_handler', 'Unknown Handler', 400 );
- break;
- }
-
- if ( !$response ) {
- $response = new Jetpack_Error( 'unknown_error', 'Unknown Error', 400 );
- }
-
- if ( is_wp_error( $response ) ) {
- $status_code = $response->get_error_data();
- $error = $response->get_error_code();
- $error_description = $response->get_error_message();
-
- if ( !is_int( $status_code ) ) {
- $status_code = 400;
- }
-
- status_header( $status_code );
- die( json_encode( (object) compact( 'error', 'error_description' ) ) );
- }
-
- status_header( 200 );
- if ( true === $response ) {
- exit;
- }
-
- die( json_encode( (object) $response ) );
- }
-
- function upload_handler() {
- if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) {
- return new Jetpack_Error( 405, get_status_header_desc( 405 ), 405 );
- }
-
- $user = wp_authenticate( '', '' );
- if ( !$user || is_wp_error( $user ) ) {
- return new Jetpack_Error( 403, get_status_header_desc( 403 ), 403 );
- }
-
- wp_set_current_user( $user->ID );
-
- if ( !current_user_can( 'upload_files' ) ) {
- return new Jetpack_Error( 'cannot_upload_files', 'User does not have permission to upload files', 403 );
- }
-
- if ( empty( $_FILES ) ) {
- return new Jetpack_Error( 'no_files_uploaded', 'No files were uploaded: nothing to process', 400 );
- }
-
- foreach ( array_keys( $_FILES ) as $files_key ) {
- if ( !isset( $_POST["_jetpack_file_hmac_{$files_key}"] ) ) {
- return new Jetpack_Error( 'missing_hmac', 'An HMAC for one or more files is missing', 400 );
- }
- }
-
- $media_keys = array_keys( $_FILES['media'] );
-
- $token = Jetpack_Data::get_access_token( get_current_user_id() );
- if ( !$token || is_wp_error( $token ) ) {
- return new Jetpack_Error( 'unknown_token', 'Unknown Jetpack token', 403 );
- }
-
- $uploaded_files = array();
- $global_post = isset( $GLOBALS['post'] ) ? $GLOBALS['post'] : null;
- unset( $GLOBALS['post'] );
- foreach ( $_FILES['media']['name'] as $index => $name ) {
- $file = array();
- foreach ( $media_keys as $media_key ) {
- $file[$media_key] = $_FILES['media'][$media_key][$index];
- }
-
- list( $hmac_provided, $salt ) = explode( ':', $_POST['_jetpack_file_hmac_media'][$index] );
-
- $hmac_file = hash_hmac_file( 'sha1', $file['tmp_name'], $salt . $token->secret );
- if ( $hmac_provided !== $hmac_file ) {
- $uploaded_files[$index] = (object) array( 'error' => 'invalid_hmac', 'error_description' => 'The corresponding HMAC for this file does not match' );
- continue;
- }
-
- $_FILES['.jetpack.upload.'] = $file;
- $post_id = isset( $_POST['post_id'][$index] ) ? absint( $_POST['post_id'][$index] ) : 0;
- if ( !current_user_can( 'edit_post', $post_id ) ) {
- $post_id = 0;
- }
- $attachment_id = media_handle_upload( '.jetpack.upload.', $post_id, array(), array(
- 'action' => 'jetpack_upload_file',
- ) );
-
- if ( !$attachment_id ) {
- $uploaded_files[$index] = (object) array( 'error' => 'unknown', 'error_description' => 'An unknown problem occurred processing the upload on the Jetpack site' );
- } elseif ( is_wp_error( $attachment_id ) ) {
- $uploaded_files[$index] = (object) array( 'error' => 'attachment_' . $attachment_id->get_error_code(), 'error_description' => $attachment_id->get_error_message() );
- } else {
- $attachment = get_post( $attachment_id );
- $uploaded_files[$index] = (object) array(
- 'id' => (string) $attachment_id,
- 'file' => $attachment->post_title,
- 'url' => wp_get_attachment_url( $attachment_id ),
- 'type' => $attachment->post_mime_type,
- 'meta' => wp_get_attachment_metadata( $attachment_id ),
- );
- }
- }
- if ( !is_null( $global_post ) ) {
- $GLOBALS['post'] = $global_post;
- }
-
- return $uploaded_files;
- }
-
- /**
- * Add help to the Jetpack page
- *
- * Deprecated. Remove when Jetpack requires WP 3.3+
- */
- function jetpack_help() {
- return
- '<p><strong>' . __( 'Jetpack by WordPress.com', 'jetpack' ) . '</strong></p>' .
- '<p>' . __( 'Jetpack supercharges your self-hosted WordPress site with the awesome cloud power of WordPress.com.', 'jetpack' ) . '</p>' .
- '<p>' . __( 'On this page, you are able to view the modules available within Jetpack, learn more about them, and activate or deactivate them as needed.', 'jetpack' ) . '</p>' .
- '<p><strong>' . __( 'Jetpack Module Options', 'jetpack' ) . '</strong></p>' .
- '<p>' . __( '<strong>To Activate/Deactivate a Module</strong> - Click on Learn More. An Activate or Deactivate button will now appear next to the Learn More button. Click the Activate/Deactivate button.', 'jetpack' ) . '</p>' .
- '<p><strong>' . __( 'For more information:', 'jetpack' ) . '</strong></p>' .
- '<p><a href="http://jetpack.me/faq/" target="_blank">' . __( 'Jetpack FAQ', 'jetpack' ) . '</a></p>' .
- '<p><a href="http://jetpack.me/support/" target="_blank">' . __( 'Jetpack Support', 'jetpack' ) . '</a></p>';
- }
-
- /**
- * Add help to the Jetpack page
- *
- * @since Jetpack (1.2.3)
- * @return false if not the Jetpack page
- */
- function admin_help() {
- $current_screen = get_current_screen();
-
- // Overview
- $current_screen->add_help_tab( array(
- 'id' => 'overview',
- 'title' => __( 'Overview', 'jetpack' ),
- 'content' =>
- '<p><strong>' . __( 'Jetpack by WordPress.com', 'jetpack' ) . '</strong></p>' .
- '<p>' . __( 'Jetpack supercharges your self-hosted WordPress site with the awesome cloud power of WordPress.com.', 'jetpack' ) . '</p>' .
- '<p>' . __( 'On this page, you are able to view the modules available within Jetpack, learn more about them, and activate or deactivate them as needed.', 'jetpack' ) . '</p>'
- ) );
-
- // Screen Content
- if ( current_user_can( 'manage_options' ) ) {
- $current_screen->add_help_tab( array(
- 'id' => 'modules',
- 'title' => __( 'Modules', 'jetpack' ),
- 'content' =>
- '<p><strong>' . __( 'Jetpack by WordPress.com', 'jetpack' ) . '</strong></p>' .
- '<p>' . __( 'You can activate or deactivate individual Jetpack modules to suit your needs.', 'jetpack' ) . '</p>' .
- '<ol>' .
- '<li>' . __( 'Find the component you want to manage', 'jetpack' ) . '</li>' .
- '<li>' . __( 'Click on Learn More', 'jetpack' ) . '</li>' .
- '<li>' . __( 'An Activate or Deactivate button will appear', 'jetpack' ) . '</li>' .
- '<li>' . __( 'If additional settings are available, a link to them will appear', 'jetpack' ) . '</li>' .
- '</ol>'
- ) );
- }
-
- // Help Sidebar
- $current_screen->set_help_sidebar(
- '<p><strong>' . __( 'For more information:', 'jetpack' ) . '</strong></p>' .
- '<p><a href="http://jetpack.me/faq/" target="_blank">' . __( 'Jetpack FAQ', 'jetpack' ) . '</a></p>' .
- '<p><a href="http://jetpack.me/support/" target="_blank">' . __( 'Jetpack Support', 'jetpack' ) . '</a></p>'
- );
- }
-
- function admin_menu_css() { ?>
- <style type="text/css" id="jetpack-menu-css">
- #toplevel_page_jetpack .wp-menu-image {
- background: url( <?php echo plugins_url( basename( dirname( __FILE__ ) ) . '/_inc/images/menuicon-sprite.png' ) ?> ) 0 90% no-repeat;
- }
- /* Retina Jetpack Menu Icon */
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- #toplevel_page_jetpack .wp-menu-image {
- background: url( <?php echo plugins_url( basename( dirname( __FILE__ ) ) . '/_inc/images/menuicon-sprite-2x.png' ) ?> ) 0 90% no-repeat;
- background-size:30px 64px;
- }
- }
- #toplevel_page_jetpack.current .wp-menu-image,
- #toplevel_page_jetpack.wp-has-current-submenu .wp-menu-image,
- #toplevel_page_jetpack:hover .wp-menu-image {
- background-position: top left;
- }
- </style><?php
- }
-
- function admin_menu_order() {
- return true;
- }
-
- function jetpack_menu_order( $menu_order ) {
- $jp_menu_order = array();
-
- foreach ( $menu_order as $index => $item ) {
- if ( $item != 'jetpack' )
- $jp_menu_order[] = $item;
-
- if ( $index == 0 )
- $jp_menu_order[] = 'jetpack';
- }
-
- return $jp_menu_order;
- }
-
- function admin_head() {
- if ( isset( $_GET['configure'] ) && Jetpack::is_module( $_GET['configure'] ) && current_user_can( 'manage_options' ) )
- do_action( 'jetpack_module_configuration_head_' . $_GET['configure'] );
- }
-
- function admin_styles() {
- global $wp_styles;
- wp_enqueue_style( 'jetpack', plugins_url( basename( dirname( __FILE__ ) ) . '/_inc/jetpack.css' ), false, JETPACK__VERSION . '-20121016' );
- $wp_styles->add_data( 'jetpack', 'rtl', true );
- }
-
- function admin_scripts() {
- wp_enqueue_script( 'jetpack-js', plugins_url( basename( dirname( __FILE__ ) ) ) . '/_inc/jetpack.js', array( 'jquery' ), JETPACK__VERSION . '-20121111' );
- wp_localize_script( 'jetpack-js', 'jetpackL10n', array(
- 'ays_disconnect' => "This will deactivate all Jetpack modules.\nAre you sure you want to disconnect?",
- 'ays_unlink' => "This will prevent user-specific modules such as Publicize, Notifications and Post By Email from working.\nAre you sure you want to unlink?",
- 'ays_dismiss' => "This will deactivate Jetpack.\nAre you sure you want to deactivate Jetpack?",
- ) );
- add_action( 'admin_footer', array( $this, 'do_stats' ) );
- }
-
- function enqueue_retina_scripts() {
- wp_enqueue_style( 'jetpack-retina', plugins_url( basename( dirname( __FILE__ ) ) . '/_inc/jetpack-retina.css' ), false, JETPACK__VERSION . '-20120730' );
- }
-
- function plugin_action_links( $actions ) {
- return array_merge(
- array( 'settings' => sprintf( '<a href="%s">%s</a>', Jetpack::admin_url(), __( 'Settings', 'jetpack' ) ) ),
- $actions
- );
- return $actions;
- }
-
- function admin_connect_notice() {
- // Don't show the connect notice on the jetpack settings page. @todo: must be a better way?
- if ( false !== strpos( $_SERVER['QUERY_STRING'], 'page=jetpack' ) )
- return;
-
- if ( !current_user_can( 'manage_options' ) )
- return;
- ?>
-
- <div id="message" class="updated jetpack-message jp-connect">
- <div id="jp-dismiss" class="jetpack-close-button-container">
- <a class="jetpack-close-button" href="?page=jetpack&jetpack-notice=dismiss" title="<?php _e( 'Dismiss this notice and deactivate Jetpack.', 'jetpack' ); ?>"><?php _e( 'Dismiss this notice and deactivate Jetpack.', 'jetpack' ); ?></a>
- </div>
- <div class="jetpack-wrap-container">
- <div class="jetpack-text-container">
- <h4>
- <?php if ( 1 == Jetpack::get_option( 'activated' ) ) : ?>
- <p><?php _e( '<strong>Your Jetpack is almost ready</strong> &#8211; A connection to WordPress.com is needed to enable features like Stats, Contact Forms, and Subscriptions. Connect now to get fueled up!', 'jetpack' ); ?></p>
- <?php else : ?>
- <p><?php _e( '<strong>Jetpack is installed</strong> and ready to bring awesome, WordPress.com cloud-powered features to your site.', 'jetpack' ) ?></p>
- <?php endif; ?>
- </h4>
- </div>
- <div class="jetpack-install-container">
- <?php if ( 1 == Jetpack::get_option( 'activated' ) ) : ?>
- <p class="submit"><a href="<?php echo $this->build_connect_url() ?>" class="button-connector" id="wpcom-connect"><?php _e( 'Connect to WordPress.com', 'jetpack' ); ?></a></p>
- <?php else : ?>
- <p class="submit"><a href="<?php echo Jetpack::admin_url() ?>" class="button-connector" id="wpcom-connect"><?php _e( 'Learn More', 'jetpack' ); ?></a></p>
- <?php endif; ?>
- </div>
- </div>
- </div>
-
- <?php
- }
-
- function network_connect_notice() {
- ?>
- <div id="message" class="updated jetpack-message">
- <div class="squeezer">
- <h4><?php _e( '<strong>Jetpack is activated!</strong> Each site on your network must be connected individually by an admin on that site.', 'jetpack' ) ?></h4>
- </div>
- </div>
- <?php
- }
-
- public static function jetpack_comment_notice() {
- if ( in_array( 'comments', Jetpack::get_active_modules() ) ) {
- return '';
- }
-
- $jetpack_old_version = explode( ':', Jetpack::get_option( 'old_version' ) );
- $jetpack_new_version = explode( ':', Jetpack::get_option( 'version' ) );
-
- if ( $jetpack_old_version ) {
- if ( version_compare( $jetpack_old_version[0], '1.4', '>=' ) ) {
- return '';
- }
- }
-
- if ( $jetpack_new_version ) {
- if ( version_compare( $jetpack_new_version[0], '1.4-something', '<' ) ) {
- return '';
- }
- }
-
- return '<br /><br />' . sprintf(
- __( 'Jetpack now includes Jetpack Comments, which enables your visitors to use their WordPress.com, Twitter, or Facebook accounts when commenting on your site. To activate Jetpack Comments, <a href="%s">%s</a>.', 'jetpack' ),
- wp_nonce_url(
- Jetpack::admin_url( array(
- 'action' => 'activate',
- 'module' => 'comments',
- ) ),
- "jetpack_activate-comments"
- ),
- __( 'click here', 'jetpack' )
- );
- }
-
- /*
- * Registration flow:
- * 1 - ::admin_page_load() action=register
- * 2 - ::try_registration()
- * 3 - ::register()
- * - Creates jetpack_register option containing two secrets and a timestamp
- * - Calls https://jetpack.wordpress.com/jetpack.register/1/ with
- * siteurl, home, gmt_offset, timezone_string, site_name, secret_1, secret_2, site_lang, timeout, stats_id
- * - That request to jetpack.wordpress.com does not immediately respond. It first makes a request BACK to this site's
- * xmlrpc.php?for=jetpack: RPC method: jetpack.verifyRegistration, Parameters: secret_1
- * - The XML-RPC request verifies secret_1, deletes both secrets and responds with: secret_2
- * - https://jetpack.wordpress.com/jetpack.register/1/ verifies that XML-RPC response (secret_2) then finally responds itself with
- * jetpack_id, jetpack_secret, jetpack_public
- * - ::register() then stores jetpack_options: id => jetpack_id, blog_token => jetpack_secret
- * 4 - redirect to https://jetpack.wordpress.com/jetpack.authorize/1/
- * 5 - user logs in with WP.com account
- * 6 - redirect to this site's wp-admin/index.php?page=jetpack&action=authorize with
- * code <-- OAuth2 style authorization code
- * 7 - ::admin_page_load() action=authorize
- * 8 - Jetpack_Client_Server::authorize()
- * 9 - Jetpack_Client_Server::get_token()
- * 10- GET https://jetpack.wordpress.com/jetpack.token/1/ with
- * client_id, client_secret, grant_type, code, redirect_uri:action=authorize, state, scope, user_email, user_login
- * 11- which responds with
- * access_token, token_type, scope
- * 12- Jetpack_Client_Server::authorize() stores jetpack_options: user_token => access_token.$user_id
- * 13- Jetpack::activate_default_modules()
- * Deactivates deprecated plugins
- * Activates all default modules
- * Catches errors: redirects to wp-admin/index.php?page=jetpack state:error=something
- * 14- redirect to this site's wp-admin/index.php?page=jetpack with state:message=authorized
- * Done!
- */
-
- /**
- * Handles the page load events for the Jetpack admin page
- */
- function admin_page_load() {
- $error = false;
-
- if ( !empty( $_GET['jetpack_restate'] ) ) {
- // Should only be used in intermediate redirects to preserve state across redirects
- Jetpack::restate();
- }
-
- if ( isset( $_GET['connect_url_redirect'] ) ) {
- // User clicked in the iframe to link their accounts
- if ( ! Jetpack::is_user_connected() ) {
- $connect_url = $this->build_connect_url( true );
- if ( isset( $_GET['notes_iframe'] ) )
- $connect_url .= '&notes_iframe';
- wp_redirect( $connect_url );
- exit;
- } else {
- Jetpack::state( 'message', 'already_authorized' );
- wp_safe_redirect( Jetpack::admin_url() );
- exit;
- }
- }
-
- if ( isset( $_GET['action'] ) ) {
- switch ( $_GET['action'] ) {
- case 'authorize' :
- if ( Jetpack::is_active() && Jetpack::is_user_connected() ) {
- Jetpack::state( 'message', 'already_authorized' );
- wp_safe_redirect( Jetpack::admin_url() );
- exit;
- }
- $client_server = new Jetpack_Client_Server;
- $client_server->authorize();
- exit;
- case 'register' :
- check_admin_referer( 'jetpack-register' );
- $registered = Jetpack::try_registration();
- if ( is_wp_error( $registered ) ) {
- $error = $registered->get_error_code();
- Jetpack::state( 'error_description', $registered->get_error_message() );
- break;
- }
-
- wp_redirect( $this->build_connect_url( true ) );
- exit;
- case 'activate' :
- $module = stripslashes( $_GET['module'] );
- check_admin_referer( "jetpack_activate-$module" );
- Jetpack::activate_module( $module );
- wp_safe_redirect( Jetpack::admin_url() );
- exit;
- case 'activate_default_modules' :
- check_admin_referer( 'activate_default_modules' );
- Jetpack::restate();
- $min_version = isset( $_GET['min_version'] ) ? $_GET['min_version'] : false;
- $max_version = isset( $_GET['max_version'] ) ? $_GET['max_version'] : false;
- $other_modules = isset( $_GET['other_modules'] ) && is_array( $_GET['other_modules'] ) ? $_GET['other_modules'] : array();
- Jetpack::activate_default_modules( $min_version, $max_version, $other_modules );
- wp_safe_redirect( Jetpack::admin_url() );
- exit;
- case 'disconnect' :
- check_admin_referer( 'jetpack-disconnect' );
- Jetpack::disconnect();
- wp_safe_redirect( Jetpack::admin_url() );
- exit;
- case 'deactivate' :
- $modules = stripslashes( $_GET['module'] );
- check_admin_referer( "jetpack_deactivate-$modules" );
- foreach ( explode( ',', $modules ) as $module ) {
- Jetpack::deactivate_module( $module );
- Jetpack::state( 'message', 'module_deactivated' );
- }
- Jetpack::state( 'module', $modules );
- wp_safe_redirect( Jetpack::admin_url() );
- exit;
- case 'unlink' :
- check_admin_referer( 'jetpack-unlink' );
- $this->unlink_user();
- Jetpack::state( 'message', 'unlinked' );
- wp_safe_redirect( Jetpack::admin_url() );
- exit;
- }
- }
-
- if ( !$error = $error ? $error : Jetpack::state( 'error' ) ) {
- $this->activate_new_modules();
- }
-
- switch ( $error ) {
- case 'access_denied' :
- $this->error = __( 'You need to authorize the Jetpack connection between your site and WordPress.com to enable the awesome features.', 'jetpack' );
- break;
- case 'wrong_state' :
- $this->error = __( "Don&#8217;t cross the streams! You need to stay logged in to your WordPress blog while you authorize Jetpack.", 'jetpack' );
- break;
- case 'invalid_client' :
- // @todo re-register instead of deactivate/reactivate
- $this->error = __( 'Return to sender. Whoops! It looks like you got the wrong Jetpack in the mail; deactivate then reactivate the Jetpack plugin to get a new one.', 'jetpack' );
- break;
- case 'invalid_grant' :
- $this->error = __( "Wrong size. Hm&#8230; it seems your Jetpack doesn&#8217;t quite fit. Have you lost weight? Click &#8220;Connect to WordPress.com&#8221; again to get your Jetpack adjusted.", 'jetpack' );
- break;
- case 'site_inaccessible' :
- case 'site_requires_authorization' :
- $this->error = sprintf( __( 'Your website needs to be publicly accessible to use Jetpack: %s', 'jetpack' ), "<code>$error</code>" );
- break;
- case 'module_activation_failed' :
- $module = Jetpack::state( 'module' );
- if ( !empty( $module ) && $mod = Jetpack::get_module( $module ) ) {
- $this->error = sprintf( __( '%s could not be activated because it triggered a <strong>fatal error</strong>. Perhaps there is a conflict with another plugin you have installed?', 'jetpack' ), $mod['name'] );
- if ( isset( $this->plugins_to_deactivate[$module] ) ) {
- $this->error .= ' ' . sprintf( __( 'Do you still have the %s plugin installed?', 'jetpack' ), $this->plugins_to_deactivate[$module][1] );
- }
- } else {
- $this->error = __( 'Module could not be activated because it triggered a <strong>fatal error</strong>. Perhaps there is a conflict with another plugin you have installed?', 'jetpack' );
- }
- if ( $php_errors = Jetpack::state( 'php_errors' ) ) {
- $this->error .= "<br />\n";
- $this->error .= $php_errors;
- }
- break;
- case 'not_public' :
- $this->error = __( "<strong>Your Jetpack has a glitch.</strong> Connecting this site with WordPress.com is not possible. This usually means your site is not publicly accessible (localhost).", 'jetpack' );
- break;
- case 'wpcom_408' :
- case 'wpcom_5??' :
- case 'wpcom_bad_response' :
- case 'wpcom_outage' :
- $this->error = __( 'WordPress.com is currently having problems and is unable to fuel up your Jetpack. Please try again later.', 'jetpack' );
- break;
- case 'register_http_request_failed' :
- case 'token_http_request_failed' :
- $this->error = sprintf( __( 'Jetpack could not contact WordPress.com: %s. This usually means something is incorrectly configured on your web host.', 'jetpack' ), "<code>$error</code>" );
- break;
- default :
- if ( empty( $error ) ) {
- break;
- }
- $error = trim( substr( strip_tags( $error ), 0, 20 ) );
- // no break: fall through
- case 'no_role' :
- case 'no_cap' :
- case 'no_code' :
- case 'no_state' :
- case 'invalid_state' :
- case 'invalid_request' :
- case 'invalid_scope' :
- case 'unsupported_response_type' :
- case 'invalid_token' :
- case 'no_token' :
- case 'missing_secrets' :
- case 'home_missing' :
- case 'siteurl_missing' :
- case 'gmt_offset_missing' :
- case 'site_name_missing' :
- case 'secret_1_missing' :
- case 'secret_2_missing' :
- case 'site_lang_missing' :
- case 'home_malformed' :
- case 'siteurl_malformed' :
- case 'gmt_offset_malformed' :
- case 'timezone_string_malformed' :
- case 'site_name_malformed' :
- case 'secret_1_malformed' :
- case 'secret_2_malformed' :
- case 'site_lang_malformed' :
- case 'secrets_mismatch' :
- case 'verify_secret_1_missing' :
- case 'verify_secret_1_malformed' :
- case 'verify_secrets_missing' :
- case 'verify_secrets_mismatch' :
- $error = esc_html( $error );
- $this->error = sprintf( __( "<strong>Your Jetpack has a glitch.</strong> Something went wrong that&#8217;s never supposed to happen. Guess you&#8217;re just lucky: %s", 'jetpack' ), "<code>$error</code>" );
- if ( !Jetpack::is_active() ) {
- $this->error .= '<br />';
- $this->error .= sprintf( __( 'Try connecting again.', 'jetpack' ) );
- }
- break;
- }
-
- $message_code = Jetpack::state( 'message' );
-
- $active_state = Jetpack::state( 'activated_modules' );
- if ( !empty( $active_state ) ) {
- $available = Jetpack::get_available_modules();
- $active_state = explode( ',', $active_state );
- $active_state = array_intersect( $active_state, $available );
- if ( count( $active_state ) ) {
- foreach ( $active_state as $mod ) {
- $this->stat( 'module-activated', $mod );
- }
- } else {
- $active_state = false;
- }
- }
-
- switch ( $message_code ) {
- case 'modules_activated' :
- $this->message = sprintf(
- __( 'Welcome to <strong>Jetpack %s</strong>!', 'jetpack' ),
- JETPACK__VERSION
- );
-
- if ( $active_state ) {
- $titles = array();
- foreach ( $active_state as $mod ) {
- if ( $mod_headers = Jetpack::get_module( $mod ) ) {
- $titles[] = '<strong>' . preg_replace( '/\s+(?![^<>]++>)/', '&nbsp;', $mod_headers['name'] ) . '</strong>';
- }
- }
- if ( $titles ) {
- $this->message .= '<br /><br />' . wp_sprintf( __( 'The following new modules have been activated: %l.', 'jetpack' ), $titles );
- }
- }
-
- if ( $reactive_state = Jetpack::state( 'reactivated_modules' ) ) {
- $titles = array();
- foreach ( explode( ',', $reactive_state ) as $mod ) {
- if ( $mod_headers = Jetpack::get_module( $mod ) ) {
- $titles[] = '<strong>' . preg_replace( '/\s+(?![^<>]++>)/', '&nbsp;', $mod_headers['name'] ) . '</strong>';
- }
- }
- if ( $titles ) {
- $this->message .= '<br /><br />' . wp_sprintf( __( 'The following modules have been updated: %l.', 'jetpack' ), $titles );
- }
- }
-
- $this->message .= Jetpack::jetpack_comment_notice();
- break;
-
- case 'module_activated' :
- if ( $module = Jetpack::get_module( Jetpack::state( 'module' ) ) ) {
- $this->message = sprintf( __( '<strong>%s Activated!</strong> You can deactivate at any time by clicking Learn More and then Deactivate on the module card.', 'jetpack' ), $module['name'] );
- $this->stat( 'module-activated', Jetpack::state( 'module' ) );
- }
- break;
-
- case 'module_deactivated' :
- $modules = Jetpack::state( 'module' );
- if ( !$modules ) {
- break;
- }
-
- $module_names = array();
- foreach ( explode( ',', $modules ) as $module_slug ) {
- $module = Jetpack::get_module( $module_slug );
- if ( $module ) {
- $module_names[] = $module['name'];
- }
-
- $this->stat( 'module-deactivated', $module_slug );
- }
-
- if ( !$module_names ) {
- break;
- }
-
- $this->message = wp_sprintf(
- _nx(
- '<strong>%l Deactivated!</strong> You can activate it again at any time using the activate button on the module card.',
- '<strong>%l Deactivated!</strong> You can activate them again at any time using the activate buttons on their module cards.',
- count( $module_names ),
- '%l = list of Jetpack module/feature names',
- 'jetpack'
- ),
- $module_names
- );
- break;
-
- case 'module_configured' :
- $this->message = __( '<strong>Module settings were saved.</strong> ', 'jetpack' );
- break;
-
- case 'already_authorized' :
- $this->message = __( '<strong>Your Jetpack is already connected.</strong> ', 'jetpack' );
- break;
-
- case 'authorized' :
- $this->message = __( "<strong>You&#8217;re fueled up and ready to go.</strong> ", 'jetpack' );
- $this->message .= "<br />\n";
- $this->message .= __( 'The features below are now active. Click the learn more buttons to explore each feature.', 'jetpack' );
- $this->message .= Jetpack::jetpack_comment_notice();
- break;
-
- case 'linked' :
- $this->message = __( "<strong>You&#8217;re fueled up and ready to go.</strong> ", 'jetpack' );
- $this->message .= Jetpack::jetpack_comment_notice();
- break;
-
- case 'unlinked' :
- $user = wp_get_current_user();
- $this->message = sprintf( __( '<strong>You have unlinked your account (%s) from WordPress.com.</strong>', 'jetpack' ), $user->user_login );
- break;
- }
-
- $deactivated_plugins = Jetpack::state( 'deactivated_plugins' );
-
- if ( !empty( $deactivated_plugins ) ) {
- $deactivated_plugins = explode( ',', $deactivated_plugins );
- $deactivated_titles = array();
- foreach ( $deactivated_plugins as $deactivated_plugin ) {
- if ( !isset( $this->plugins_to_deactivate[$deactivated_plugin] ) ) {
- continue;
- }
-
- $deactivated_titles[] = '<strong>' . str_replace( ' ', '&nbsp;', $this->plugins_to_deactivate[$deactivated_plugin][1] ) . '</strong>';
- }
-
- if ( $deactivated_titles ) {
- if ( $this->message ) {
- $this->message .= "<br /><br />\n";
- }
-
- $this->message .= wp_sprintf( _n(
- 'Jetpack contains the most recent version of the old %l plugin.',
- 'Jetpack contains the most recent versions of the old %l plugins.',
- count( $deactivated_titles ),
- 'jetpack'
- ), $deactivated_titles );
-
- $this->message .= "<br />\n";
-
- $this->message .= _n(
- 'The old version has been deactivated and can be removed from your site.',
- 'The old versions have been deactivated and can be removed from your site.',
- count( $deactivated_titles ),
- 'jetpack'
- );
- }
- }
-
- $this->privacy_checks = Jetpack::state( 'privacy_checks' );
-
- if ( $this->message || $this->error || $this->privacy_checks ) {
- add_action( 'jetpack_notices', array( $this, 'admin_notices' ) );
- }
-
- if ( isset( $_GET['configure'] ) && Jetpack::is_module( $_GET['configure'] ) && current_user_can( 'manage_options' ) ) {
- do_action( 'jetpack_module_configuration_load_' . $_GET['configure'] );
- }
-
- add_filter( 'jetpack_short_module_description', 'wptexturize' );
- }
-
- function admin_notices() {
-
- if ( $this->error ) {
-?>
-<div id="message" class="jetpack-message jetpack-err">
- <div class="squeezer">
- <h4><?php echo wp_kses( $this->error, array( 'code' => true, 'strong' => true, 'br' => true, 'b' => true ) ); ?></h4>
-<?php if ( $desc = Jetpack::state( 'error_description' ) ) : ?>
- <p><?php echo esc_html( stripslashes( $desc ) ); ?></p>
-<?php endif; ?>
- </div>
-</div>
-<?php
- }
-
- if ( $this->message ) {
-?>
-<div id="message" class="jetpack-message">
- <div class="squeezer">
- <h4><?php echo wp_kses( $this->message, array( 'strong' => array(), 'a' => array( 'href' => true ), 'br' => true ) ); ?></h4>
- </div>
-</div>
-<?php
-
- }
-
- if ( $this->privacy_checks ) :
- $module_names = $module_slugs = array();
-
- $privacy_checks = explode( ',', $this->privacy_checks );
- foreach ( $privacy_checks as $module_slug ) {
- $module = Jetpack::get_module( $module_slug );
- if ( !$module ) {
- continue;
- }
-
- $module_slugs[] = $module_slug;
- $module_names[] = "<strong>{$module['name']}</strong>";
- }
-
- $module_slugs = join( ',', $module_slugs );
-?>
-<div id="message" class="jetpack-message jetpack-err">
- <div class="squeezer">
- <h4><strong><?php esc_html_e( 'Is this site private?', 'jetpack' ); ?></strong></h4><br />
- <p><?php
- echo wp_kses( wptexturize( wp_sprintf(
- _nx(
- "Like your site's RSS feeds, %l allows access to your posts and other content to third parties.",
- "Like your site's RSS feeds, %l allow access to your posts and other content to third parties.",
- count( $privacy_checks ),
- '%l = list of Jetpack module/feature names',
- 'jetpack'
- ),
- $module_names
- ) ), array( 'strong' => true ) );
-
- echo "\n<br />\n";
-
- echo wp_kses( sprintf(
- _nx(
- 'If your site is not publicly accessible, consider <a href="%1$s" title="%2$s">deactivating this feature</a>.',
- 'If your site is not publicly accessible, consider <a href="%1$s" title="%2$s">deactivating these features</a>.',
- count( $privacy_checks ),
- '%1$s = deactivation URL, %2$s = "Deactivate {list of Jetpack module/feature names}',
- 'jetpack'
- ),
- wp_nonce_url(
- Jetpack::admin_url( array(
- 'action' => 'deactivate',
- 'module' => urlencode( $module_slugs ),
- ) ),
- "jetpack_deactivate-$module_slugs"
- ),
- esc_attr( wp_kses( wp_sprintf( _x( 'Deactivate %l', '%l = list of Jetpack module/feature names', 'jetpack' ), $module_names ), array() ) )
- ), array( 'a' => array( 'href' => true, 'title' => true ) ) );
- ?></p>
- </div>
-</div>
-<?php
- endif;
- }
-
- /**
- * Record a stat for later output
- */
- function stat( $group, $detail ) {
- if ( !isset( $this->stats[ $group ] ) )
- $this->stats[ $group ] = array();
- $this->stats[ $group ][] = $detail;
- }
-
- /**
- * Load stats pixels. $group is auto-prefixed with "jetpack-"
- */
- function do_stats() {
- if ( is_array( $this->stats ) && count( $this->stats ) ) {
- foreach ( $this->stats as $group => $stats ) {
- if ( is_array( $stats ) && count( $stats ) )
- echo '<img src="' . ( is_ssl() ? 'https' : 'http' ) . '://stats.wordpress.com/g.gif?v=wpcom2&x_jetpack-' . esc_attr( $group ) . '=' . esc_attr( implode( ',', $stats ) ) . '&rand=' . md5( mt_rand( 0, 999 ) . time() ) . '" width="1" height="1" style="display:none;" />';
- }
- }
- }
-
- function translate_current_user_to_role() {
- foreach ( $this->capability_translations as $role => $cap ) {
- if ( current_user_can( $role ) || current_user_can( $cap ) ) {
- return $role;
- }
- }
-
- return false;
- }
-
- function translate_role_to_cap( $role ) {
- if ( !isset( $this->capability_translations[$role] ) ) {
- return false;
- }
-
- return $this->capability_translations[$role];
- }
-
- function sign_role( $role ) {
- if ( !$user_id = (int) get_current_user_id() ) {
- return false;
- }
-
- $token = Jetpack_Data::get_access_token();
- if ( !$token || is_wp_error( $token ) ) {
- return false;
- }
-
- return $role . ':' . hash_hmac( 'md5', "{$role}|{$user_id}", $token->secret );
- }
-
- function build_connect_url( $raw = false, $redirect = false ) {
- if ( !Jetpack::get_option( 'blog_token' ) ) {
- $url = wp_nonce_url( add_query_arg( 'action', 'register', menu_page_url( 'jetpack', false ) ), 'jetpack-register' );
- } else {
- $role = $this->translate_current_user_to_role();
- $signed_role = $this->sign_role( $role );
-
- $user = wp_get_current_user();
-
- $redirect = $redirect ? esc_url_raw( $redirect ) : '';
-
- $args = urlencode_deep( array(
- 'response_type' => 'code',
- 'client_id' => Jetpack::get_option( 'id' ),
- 'redirect_uri' => add_query_arg( array(
- 'action' => 'authorize',
- '_wpnonce' => wp_create_nonce( "jetpack-authorize_{$role}_{$redirect}" ),
- 'redirect' => $redirect ? urlencode( $redirect ) : false,
- ), menu_page_url( 'jetpack', false ) ),
- 'state' => $user->ID,
- 'scope' => $signed_role,
- 'user_email' => $user->user_email,
- 'user_login' => $user->user_login,
- 'is_active' => Jetpack::is_active(),
- ) );
-
- $url = add_query_arg( $args, Jetpack::api_url( 'authorize' ) );
- }
-
- return $raw ? $url : esc_url( $url );
- }
-
- public static function admin_url( $args = null ) {
- $url = admin_url( 'admin.php?page=jetpack' );
- if ( is_array( $args ) )
- $url = add_query_arg( $args, $url );
- return $url;
- }
-
- function dismiss_jetpack_notice() {
- if ( isset( $_GET['jetpack-notice'] ) && 'dismiss' == $_GET['jetpack-notice'] && ! is_plugin_active_for_network( plugin_basename( __FILE__ ) ) ) {
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
-
- deactivate_plugins( plugin_basename( __FILE__ ), false, false );
-
- wp_safe_redirect( admin_url() . 'plugins.php?deactivate=true&plugin_status=all&paged=1&s=' );
- exit;
- }
- }
-
- function admin_page() {
- global $current_user;
-
- $role = $this->translate_current_user_to_role();
- $is_connected = Jetpack::is_active();
- $user_token = Jetpack_Data::get_access_token($current_user->ID);
- $is_user_connected = $user_token && !is_wp_error($user_token);
- $is_master_user = $current_user->ID == Jetpack::get_option( 'master_user' );
- $module = false;
- ?>
- <div class="wrap" id="jetpack-settings">
-
- <h2 style="display: none"></h2> <!-- For WP JS message relocation -->
-
- <div id="jp-header"<?php if ( $is_connected ) : ?> class="small"<?php endif; ?>>
- <div id="jp-clouds">
- <?php if ( $is_connected ) : ?>
- <div id="jp-disconnectors">
- <?php if ( current_user_can( 'manage_options' ) ) : ?>
- <div id="jp-disconnect" class="jp-disconnect">
- <a href="<?php echo wp_nonce_url( Jetpack::admin_url( array( 'action' => 'disconnect' ) ), 'jetpack-disconnect' ); ?>"><div class="deftext"><?php _e( 'Connected to WordPress.com', 'jetpack' ); ?></div><div class="hovertext"><?php _e( 'Disconnect from WordPress.com', 'jetpack' ) ?></div></a>
- </div>
- <?php endif; ?>
- <?php if ( $is_user_connected && !$is_master_user ) : ?>
- <div id="jp-unlink" class="jp-disconnect">
- <a href="<?php echo wp_nonce_url( Jetpack::admin_url( array( 'action' => 'unlink' ) ), 'jetpack-unlink' ); ?>"><div class="deftext"><?php _e( 'User linked to WordPress.com', 'jetpack' ); ?></div><div class="hovertext"><?php _e( 'Unlink user from WordPress.com', 'jetpack' ) ?></div></a>
- </div>
- <?php endif; ?>
- </div>
- <?php endif; ?>
- <h3><?php _e( 'Jetpack by WordPress.com', 'jetpack' ) ?></h3>
- <?php if ( !$is_connected ) : ?>
- <div id="jp-notice">
- <p><?php _e( 'Jetpack supercharges your self-hosted WordPress site with the awesome cloud power of WordPress.com.', 'jetpack' ); ?></p>
- </div>
- <?php endif; ?>
- </div>
- </div>
-
- <?php if ( isset( $_GET['jetpack-notice'] ) && 'dismiss' == $_GET['jetpack-notice'] ) : ?>
- <div id="message" class="error">
- <p><?php _e( 'Jetpack is network activated and notices can not be dismissed.', 'jetpack' ); ?></p>
- </div>
- <?php endif; ?>
-
- <?php do_action( 'jetpack_notices' ) ?>
-
- <?php // If the connection has not been made then show the marketing text. ?>
- <?php if ( ! $is_connected ) : ?>
-
- <div id="message" class="updated jetpack-message jp-connect">
- <div id="jp-dismiss" class="jetpack-close-button-container">
- <a class="jetpack-close-button" href="?page=jetpack&jetpack-notice=dismiss" title="<?php _e( 'Dismiss this notice.', 'jetpack' ); ?>"><?php _e( 'Dismiss this notice.', 'jetpack' ); ?></a>
- </div>
- <div class="jetpack-wrap-container">
- <div class="jetpack-text-container">
- <h4>
- <p><?php _e( "To enable all of the Jetpack features you&#8217;ll need to connect your website to WordPress.com using the button to the right. Once you&#8217;ve made the connection you&#8217;ll activate all the delightful features below.", 'jetpack' ) ?></p>
- </h4>
- </div>
- <div class="jetpack-install-container">
- <p class="submit"><a href="<?php echo $this->build_connect_url() ?>" class="button-connector" id="wpcom-connect"><?php _e( 'Connect to WordPress.com', 'jetpack' ); ?></a></p>
- </div>
- </div>
- </div>
-
- <?php elseif ( ! $is_user_connected ) : ?>
-
- <div id="message" class="updated jetpack-message jp-connect">
- <div class="jetpack-wrap-container">
- <div class="jetpack-text-container">
- <h4>
- <p><?php _e( "To enable all of the Jetpack features you&#8217;ll need to link your account here to your WordPress.com account using the button to the right.", 'jetpack' ) ?></p>
- </h4>
- </div>
- <div class="jetpack-install-container">
- <p class="submit"><a href="<?php echo $this->build_connect_url() ?>" class="button-connector" id="wpcom-connect"><?php _e( 'Link account with WordPress.com', 'jetpack' ); ?></a></p>
- </div>
- </div>
- </div>
-
- <?php else /* blog and user are connected */ : ?>
- <?php /* TODO: if not master user, show user disconnect button? */ ?>
- <?php endif; ?>
-
- <?php
- // If we select the configure option for a module, show the configuration screen.
- if ( isset( $_GET['configure'] ) && Jetpack::is_module( $_GET['configure'] ) && current_user_can( 'manage_options' ) ) :
- $this->admin_screen_configure_module( $_GET['configure'] );
-
- // List all the available modules.
- else :
- $this->admin_screen_list_modules();
- ?>
-
- <div id="survey" class="jp-survey">
- <div class="jp-survey-container">
- <div class="jp-survey-text">
- <h4><?php _e( 'Have feedback on Jetpack?', 'jetpack' ); ?></h4>
- <br />
- <?php _e( 'Answer a short survey to let us know how we&#8217;re doing and what to add in the future.', 'jetpack' ); ?>
- </div>
- <div class="jp-survey-button-container">
- <p class="submit"><?php printf( '<a id="jp-survey-button" class="button-primary" target="_blank" href="%1$s">%2$s</a>', 'http://jetpack.me/survey/?rel=' . JETPACK__VERSION, __( 'Take Survey', 'jetpack' ) ); ?></p>
- </div>
- </div>
- </div>
-
- <?php if ( $is_connected && $this->current_user_is_connection_owner() ) : ?>
- <p id="news-sub"><?php _e( 'Checking email updates status&hellip;', 'jetpack' ); ?></p>
- <script type="text/javascript">
- jQuery(document).ready(function($){
- $.get( ajaxurl, { action: 'jetpack-check-news-subscription', rand: jQuery.now().toString() + Math.random().toString() }, function( data ) {
- if ( 'subscribed' == data ) {
- $( '#news-sub' ).html( '<?php printf(
- esc_js( _x( 'You are currently subscribed to email updates. %s', '%s = Unsubscribe link', 'jetpack' ) ),
- '<a href="#" class="jp-news-link button">' . esc_js( __( 'Unsubscribe', 'jetpack' ) ) . '</a>'
- ); ?>' );
- } else {
- $( '#news-sub' ).html( '<?php printf(
- esc_js( _x( 'Want to receive updates about Jetpack by email? %s', '%s = Subscribe link', 'jetpack' ) ),
- '<a href="#" class="jp-news-link button-primary">' . esc_js( __( 'Subscribe', 'jetpack' ) ) . '</a>'
- ); ?>' );
- }
- $( '.jp-news-link' ).click( function() {
- $( '#news-sub' ).append( ' <img src="<?php echo esc_js( esc_url( admin_url( 'images/loading.gif' ) ) ); ?>" align="absmiddle" id="jp-news-loading" />' );
- $.get( ajaxurl, { action: 'jetpack-subscribe-to-news', rand: jQuery.now().toString() + Math.random().toString() }, function( data ) {
- if ( 'subscribed' == data ) {
- $( '#news-sub' ).text( '<?php echo esc_js( __( 'You have been subscribed to receive email updates.', 'jetpack' ) ); ?>' );
- } else {
- $( '#news-sub' ).text( '<?php echo esc_js( __( 'You will no longer receive email updates about Jetpack.', 'jetpack' ) ); ?>' );
- }
- $( '#jp-news-loading' ).remove();
- } );
- return false;
- } );
- } );
- } );
- </script>
- <?php endif; ?>
- <?php endif; ?>
-
- <div id="jp-footer">
- <p class="automattic"><?php _e( 'An <span>Automattic</span> Airline', 'jetpack' ) ?></p>
- <p class="small">
- <a href="http://jetpack.me/" target="_blank">Jetpack <?php echo esc_html( JETPACK__VERSION ); ?></a> |
- <a href="http://automattic.com/privacy/" target="_blank"><?php _e( 'Privacy Policy', 'jetpack' ); ?></a> |
- <a href="http://wordpress.com/tos/" target="_blank"><?php _e( 'Terms of Service', 'jetpack' ); ?></a> |
-<?php if ( current_user_can( 'manage_options' ) ) : ?>
- <a href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin-ajax.php?action=jetpack_debug' ), 'jetpack_debug' ) ); ?>" id="jp-debug"><?php _e( 'Debug', 'jetpack' ); ?></a> |
-<?php endif; ?>
- <a href="http://jetpack.me/support/" target="_blank"><?php _e( 'Support', 'jetpack' ); ?></a>
- </p>
- </div>
-
- <div id="jetpack-configuration" style="display:none;">
- <p><img width="16" src="<?php echo esc_url( plugins_url( '_inc/images/wpspin_light-2x.gif', __FILE__ ) ); ?>" alt="Loading ..." /></p>
- </div>
- </div>
- <?php
- }
-
- function ajax_debug() {
- nocache_headers();
-
- check_ajax_referer( 'jetpack_debug' );
-
- if ( !current_user_can( 'manage_options' ) ) {
- die( '-1' );
- }
-?>
- <p><?php esc_html_e( 'This is sensitive information. Please do not post your BLOG_TOKEN or USER_TOKEN publicly; they are like passwords.', 'jetpack' ); ?></p>
- <ul>
- <?php
- // Extract the current_user's token
- $user_id = get_current_user_id();
- $user_tokens = Jetpack::get_option( 'user_tokens' );
- if ( is_array( $user_tokens ) && array_key_exists( $user_id, $user_tokens ) ) {
- $user_token = $user_tokens[$user_id];
- } else {
- $user_token = '[this user has no token]';
- }
- unset( $user_tokens );
-
- foreach ( array(
- 'CLIENT_ID' => 'id',
- 'BLOG_TOKEN' => 'blog_token',
- 'MASTER_USER' => 'master_user',
- 'CERT' => 'fallback_no_verify_ssl_certs',
- 'TIME_DIFF' => 'time_diff',
- 'VERSION' => 'version',
- 'OLD_VERSION' => 'old_version',
- 'PUBLIC' => 'public',
- ) as $label => $option_name ) :
- ?>
- <li><?php echo esc_html( $label ); ?>: <code><?php echo esc_html( Jetpack::get_option( $option_name ) ); ?></code></li>
- <?php endforeach; ?>
- <li>USER_ID: <code><?php echo esc_html( $user_id ); ?></code></li>
- <li>USER_TOKEN: <code><?php echo esc_html( $user_token ); ?></code></li>
- <li>PHP_VERSION: <code><?php echo esc_html( PHP_VERSION ); ?></code></li>
- <li>WORDPRESS_VERSION: <code><?php echo esc_html( $GLOBALS['wp_version'] ); ?></code></li>
- </ul>
-<?php
- exit;
- }
-
- function admin_screen_configure_module( $module_id ) {
- if ( !in_array( $module_id, Jetpack::get_active_modules() ) || !current_user_can( 'manage_options' ) )
- return false; ?>
-
- <div id="jp-settings-screen" style="position: relative">
- <h3>
- <?php
- $module = Jetpack::get_module( $module_id );
- echo '<a href="' . menu_page_url( 'jetpack', false ) . '">' . __( 'Jetpack by WordPress.com', 'jetpack' ) . '</a> &rarr; ';
- printf( __( 'Configure %s', 'jetpack' ), $module['name'] );
- ?>
- </h3>
-
- <?php do_action( 'jetpack_module_configuration_screen_' . $module_id ); ?>
- </div><?php
- }
-
- public static function sort_modules( $a, $b ) {
- if ( $a['sort'] == $b['sort'] )
- return 0;
-
- return ( $a['sort'] < $b['sort'] ) ? -1 : 1;
- }
-
- function admin_screen_list_modules() {
- require_once dirname( __FILE__ ) . '/modules/module-info.php';
- $jetpack_connected = true;
- if ( !Jetpack::is_active() )
- $jetpack_connected = false;
-
- ?>
- <div class="module-container">
- <?php
-
- $avail_raw = Jetpack::get_available_modules();
- $available = array();
- $active = Jetpack::get_active_modules();
- $counter = 0;
-
- foreach ( (array) $avail_raw as $module ) {
- if ( $plugin = Jetpack::get_module( $module ) ) {
- $plugin['module'] = $module;
- $available[] = $plugin;
- }
- }
- unset( $avail_raw );
- usort( $available, array( 'Jetpack', 'sort_modules' ) );
- $jetpack_version = Jetpack::get_option( 'version' );
- if ( $jetpack_version ) {
- list( $jetpack_version, $jetpack_version_time ) = explode( ':', $jetpack_version );
- } else {
- $jetpack_version = 0;
- $jetpack_version_time = 0;
- }
-
- $jetpack_old_version = Jetpack::get_option( 'old_version' );
- if ( $jetpack_old_version ) {
- list( $jetpack_old_version ) = explode( ':', $jetpack_old_version );
- } else {
- $jetpack_old_version = 0;
- }
- $now = time();
-
- foreach ( (array) $available as $module_data ) {
- $module = $module_data['module'];
- $activated = in_array( $module, $active );
- if ( $activated ) {
- $css = 'active';
- $toggle = __( 'Deactivate', 'jetpack' );
- $toggle_url = wp_nonce_url(
- Jetpack::admin_url( array(
- 'action' => 'deactivate',
- 'module' => $module
- ) ),
- "jetpack_deactivate-$module"
- );
- } else {
- $css = 'inactive';
- $toggle = __( 'Activate', 'jetpack' );
- $toggle_url = wp_nonce_url(
- Jetpack::admin_url( array(
- 'action' => 'activate',
- 'module' => $module
- ) ),
- "jetpack_activate-$module"
- );
- }
-
- if ( $counter % 4 == 0 ) {
- $classes = $css . ' jetpack-newline';
- $counter = 0;
- } else {
- $classes = $css;
- }
-
- $free_text = esc_html( $module_data['free'] ? __( 'Free', 'jetpack' ) : __( 'Purchase', 'jetpack' ) );
- $free_text = apply_filters( 'jetpack_module_free_text_' . $module, $free_text );
- $badge_text = $free_text;
-
- if ( !$jetpack_connected ) {
- $classes = 'x disabled';
- } else if ( $jetpack_version_time + 604800 > $now ) { // 1 week
- if ( version_compare( $module_data['introduced'], $jetpack_old_version, '>' ) ) {
- $badge_text = esc_html__( 'New', 'jetpack' );
- $classes .= ' jetpack-new-module';
- } elseif ( isset( $module_data['changed'] ) && version_compare( $module_data['changed'], $jetpack_old_version, '>' ) ) {
- $badge_text = esc_html__( 'Updated', 'jetpack' );
- $classes .= ' jetpack-updated-module';
- } else {
- $badge_text = $free_text;
- }
- }
-
- ?>
- <div class="jetpack-module jetpack-<?php echo $classes; ?>" id="<?php echo $module ?>">
- <h3><?php echo $module_data['name']; ?></h3>
- <div class="jetpack-module-description">
- <div class="module-image">
- <p><span class="module-image-badge"><?php echo $badge_text; ?></span><span class="module-image-free" style="display: none"><?php echo $free_text; ?></span></p>
- </div>
-
- <p><?php echo apply_filters( 'jetpack_short_module_description', $module_data['description'], $module ); ?></p>
- </div>
-
- <div class="jetpack-module-actions">
- <?php if ( $jetpack_connected ) : ?>
- <?php if ( !$activated && current_user_can( 'manage_options' ) && apply_filters( 'jetpack_can_activate_' . $module, true ) ) : ?>
- <a href="<?php echo esc_url( $toggle_url ); ?>" class="<?php echo ( 'inactive' == $css ? ' button-primary' : ' button-secondary' ); ?>"><?php echo $toggle; ?></a>&nbsp;
- <?php endif; ?>
-
- <?php do_action( 'jetpack_learn_more_button_' . $module ) ?>
-
- <?php
- if ( current_user_can( 'manage_options' ) && apply_filters( 'jetpack_module_configurable_' . $module, false ) ) {
- echo '<a href="' . esc_attr( Jetpack::module_configuration_url( $module ) ) . '" class="jetpack-configure-button button-secondary">' . __( 'Configure', 'jetpack' ) . '</a>';
- }
- ?><?php if ( $activated && $module_data['deactivate'] && current_user_can( 'manage_options' ) ) : ?><a style="display: none;" href="<?php echo esc_url( $toggle_url ); ?>" class="jetpack-deactivate-button button-secondary"><?php echo $toggle; ?></a>&nbsp;<?php endif; ?>
-
- <?php else : ?>
- <?php do_action( 'jetpack_learn_more_button_' . $module ) ?>
- <?php endif; ?>
- </div>
- </div>
- <?php if ( 'inactive' == $css && $jetpack_connected ) : ?>
- <script type="text/javascript">
- jQuery( '#<?php echo esc_js( $module ); ?>' ).bind( 'click', function(e){
- if ( !jQuery(e.target).hasClass('more-info-link') )
- document.location.href = '<?php echo str_replace( '&amp;', '&', esc_js( esc_url( $toggle_url ) ) ); ?>';
- } );
- </script>
- <?php endif; ?>
-
- <div id="jp-more-info-<?php echo esc_attr( $module ); ?>" style="display:none;">
- <?php
- if ( $jetpack_connected && has_action( 'jetpack_module_more_info_connected_' . $module ) )
- do_action( 'jetpack_module_more_info_connected_' . $module );
- else
- do_action( 'jetpack_module_more_info_' . $module );
- ?>
- </div>
-
- <?php
- $counter++;
- }
-
- // Add in some "Coming soon..." placeholders to fill up the current row and one more
- for ( $i = 0; $i < 4; $i++ ) { ?>
- <div class="jetpack-module placeholder"<?php if ( $i > 8 - $counter ) echo ' style="display: none;"'; ?>>
- <h3><?php _e( 'Coming soon&#8230;', 'jetpack' ) ?></h3>
- </div>
- <?php
- }
-
- echo '</div><!-- .module-container -->';
- }
-
- function check_news_subscription() {
- if ( !$this->current_user_is_connection_owner() ) {
- exit;
- }
-
- Jetpack::load_xml_rpc_client();
- $xml = new Jetpack_IXR_Client( array(
- 'user_id' => JETPACK_MASTER_USER,
- ) );
- $xml->query( 'jetpack.checkNewsSubscription' );
- if ( $xml->isError() ) {
- printf( '%s: %s', $xml->getErrorCode(), $xml->getErrorMessage() );
- } else {
- print_r( $xml->getResponse() );
- }
- exit;
- }
-
- function subscribe_to_news() {
- if ( !$this->current_user_is_connection_owner() ) {
- exit;
- }
-
- Jetpack::load_xml_rpc_client();
- $xml = new Jetpack_IXR_Client( array(
- 'user_id' => JETPACK_MASTER_USER,
- ) );
- $xml->query( 'jetpack.subscribeToNews' );
- if ( $xml->isError() ) {
- printf( '%s: %s', $xml->getErrorCode(), $xml->getErrorMessage() );
- } else {
- print_r( $xml->getResponse() );
- }
- exit;
- }
-
-/* Client API */
-
- /**
- * Returns the requested Jetpack API URL
- *
- * @return string
- */
- public static function api_url( $relative_url ) {
- return trailingslashit( JETPACK__API_BASE . $relative_url ) . JETPACK__API_VERSION . '/';
- }
-
- /**
- * Some hosts disable the OpenSSL extension and so cannot make outgoing HTTPS requsets
- */
- public static function fix_url_for_bad_hosts( $url, &$args ) {
- if ( 0 !== strpos( $url, 'https://' ) ) {
- return $url;
- }
-
- switch ( JETPACK_CLIENT__HTTPS ) {
- case 'ALWAYS' :
- return $url;
- case 'NEVER' :
- return substr_replace( $url, '', 4, 1 );
- // default : case 'AUTO' :
- }
-
- $jetpack = Jetpack::init();
-
- // Yay! Your host is good!
- if ( wp_http_supports( array( 'ssl' => true ) ) ) {
- return $url;
- }
-
- // Boo! Your host is bad and makes Jetpack cry!
- return substr_replace( $url, '', 4, 1 );
- }
-
- /**
- * Returns the Jetpack XML-RPC API
- *
- * @return string
- */
- public static function xmlrpc_api_url() {
- $base = preg_replace( '#(https?://[^?/]+)(/?.*)?$#', '\\1', JETPACK__API_BASE );
- return untrailingslashit( $base ) . '/xmlrpc.php';
- }
-
- /**
- * @return bool|WP_Error
- */
- public static function register() {
- Jetpack::update_option( 'register', wp_generate_password( 32, false ) . ':' . wp_generate_password( 32, false ) . ':' . ( time() + 600 ) );
-
- @list( $secret_1, $secret_2, $secret_eol ) = explode( ':', Jetpack::get_option( 'register' ) );
- if ( empty( $secret_1 ) || empty( $secret_2 ) || empty( $secret_eol ) || $secret_eol < time() )
- return new Jetpack_Error( 'missing_secrets' );
-
- $timeout = (int) ini_get( 'max_execution_time' );
- if ( !$timeout )
- $timeout = 30;
- $timeout = intval( $timeout / 2 );
-
- $gmt_offset = get_option( 'gmt_offset' );
- if ( !$gmt_offset ) {
- $gmt_offset = 0;
- }
-
- $stats_options = get_option( 'stats_options' );
- $stats_id = isset($stats_options['blog_id']) ? $stats_options['blog_id'] : null;
-
- $args = array(
- 'method' => 'POST',
- 'body' => array(
- 'siteurl' => site_url(),
- 'home' => home_url(),
- 'gmt_offset' => $gmt_offset,
- 'timezone_string' => (string) get_option( 'timezone_string' ),
- 'site_name' => (string) get_option( 'blogname' ),
- 'secret_1' => $secret_1,
- 'secret_2' => $secret_2,
- 'site_lang' => get_locale(),
- 'timeout' => $timeout,
- 'stats_id' => $stats_id,
- ),
- 'headers' => array(
- 'Accept' => 'application/json',
- ),
- 'timeout' => $timeout,
- );
- $response = Jetpack_Client::_wp_remote_request( Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'register' ), $args ), $args, true );
-
- if ( is_wp_error( $response ) ) {
- return new Jetpack_Error( 'register_http_request_failed', $response->get_error_message() );
- }
-
- $code = wp_remote_retrieve_response_code( $response );
- $entity = wp_remote_retrieve_body( $response );
-
- if ( $entity )
- $json = json_decode( $entity );
- else
- $json = false;
-
- $code_type = intval( $code / 100 );
- if ( 5 == $code_type ) {
- return new Jetpack_Error( 'wpcom_5??', sprintf( __( 'Error Details: %s', 'jetpack' ), $code ), $code );
- } elseif ( 408 == $code ) {
- return new Jetpack_Error( 'wpcom_408', sprintf( __( 'Error Details: %s', 'jetpack' ), $code ), $code );
- } elseif ( !empty( $json->error ) ) {
- $error_description = isset( $json->error_description ) ? sprintf( __( 'Error Details: %s', 'jetpack' ), (string) $json->error_description ) : '';
- return new Jetpack_Error( (string) $json->error, $error_description, $code );
- } elseif ( 200 != $code ) {
- return new Jetpack_Error( 'wpcom_bad_response', sprintf( __( 'Error Details: %s', 'jetpack' ), $code ), $code );
- }
-
- // Jetpack ID error block
- if ( empty( $json->jetpack_id ) ) {
- return new Jetpack_Error( 'jetpack_id', sprintf( __( 'Error Details: Jetpack ID is empty. Do not publicly post this error message! %s', 'jetpack' ), $entity ), $entity );
- } elseif ( ! is_scalar( $json->jetpack_id ) ) {
- return new Jetpack_Error( 'jetpack_id', sprintf( __( 'Error Details: Jetpack ID is not a scalar. Do not publicly post this error message! %s', 'jetpack' ) , $entity ), $entity );
- } elseif ( preg_match( '/[^0-9]/', $json->jetpack_id ) ) {
- return new Jetpack_Error( 'jetpack_id', sprintf( __( 'Error Details: Jetpack ID begins with a numeral. Do not publicly post this error message! %s', 'jetpack' ) , $entity ), $entity);
- }
-
- if ( empty( $json->jetpack_secret ) || !is_string( $json->jetpack_secret ) )
- return new Jetpack_Error( 'jetpack_secret', '', $code );
-
- if ( isset( $json->jetpack_public ) ) {
- $jetpack_public = (int) $json->jetpack_public;
- } else {
- $jetpack_public = false;
- }
-
- Jetpack::update_options( array(
- 'id' => (int) $json->jetpack_id,
- 'blog_token' => (string) $json->jetpack_secret,
- 'public' => $jetpack_public,
- ) );
-
- return true;
- }
-
-
-/* Client Server API */
-
- /**
- * Loads the Jetpack XML-RPC client
- */
- public static function load_xml_rpc_client() {
- require_once ABSPATH . WPINC . '/class-IXR.php';
- require_once dirname( __FILE__ ) . '/class.jetpack-ixr-client.php';
- }
-
- /**
- * Authenticates XML-RPC and other requests from the Jetpack Server
- */
- function authenticate_jetpack( $user, $username, $password ) {
- if ( is_a( $user, 'WP_User' ) ) {
- return $user;
- }
-
- // It's not for us
- if ( !isset( $_GET['token'] ) || empty( $_GET['signature'] ) ) {
- return $user;
- }
-
- @list( $token_key, $version, $user_id ) = explode( ':', $_GET['token'] );
- if (
- empty( $token_key )
- ||
- empty( $version ) || strval( JETPACK__API_VERSION ) !== $version
- ||
- empty( $user_id ) || !ctype_digit( $user_id ) || !get_userdata( $user_id ) // only handle user_tokens for now, not blog_tokens
- ) {
- return $user;
- }
-
- $token = Jetpack_Data::get_access_token( $user_id );
- if ( !$token ) {
- return $user;
- }
-
- if ( 0 !== strpos( $token->secret, "$token_key." ) ) {
- return $user;
- }
-
- require_once dirname( __FILE__ ) . '/class.jetpack-signature.php';
-
- $jetpack_signature = new Jetpack_Signature( $token->secret, (int) Jetpack::get_option( 'time_diff' ) );
- if ( isset( $_POST['_jetpack_is_multipart'] ) ) {
- $post_data = $_POST;
- $file_hashes = array();
- foreach ( $post_data as $post_data_key => $post_data_value ) {
- if ( 0 !== strpos( $post_data_key, '_jetpack_file_hmac_' ) ) {
- continue;
- }
- $post_data_key = substr( $post_data_key, strlen( '_jetpack_file_hmac_' ) );
- $file_hashes[$post_data_key] = $post_data_value;
- }
-
- foreach ( $file_hashes as $post_data_key => $post_data_value ) {
- unset( $post_data["_jetpack_file_hmac_{$post_data_key}"] );
- $post_data[$post_data_key] = $post_data_value;
- }
-
- ksort( $post_data );
-
- $body = http_build_query( stripslashes_deep( $post_data ) );
- } elseif ( is_null( $this->HTTP_RAW_POST_DATA ) ) {
- $body = file_get_contents( 'php://input' );
- } else {
- $body = null;
- }
- $signature = $jetpack_signature->sign_current_request( array(
- 'body' => is_null( $body ) ? $this->HTTP_RAW_POST_DATA : $body
- ) );
-
- if ( !$signature ) {
- return $user;
- } else if ( is_wp_error( $signature ) ) {
- return $signature;
- } else if ( $signature !== $_GET['signature'] ) {
- return $user;
- }
-
- $timestamp = (int) $_GET['timestamp'];
- $nonce = stripslashes( (string) $_GET['nonce'] );
-
- if ( !$this->add_nonce( $timestamp, $nonce ) ) {
- return $user;
- }
-
- nocache_headers();
-
- return new WP_User( $token->external_user_id );
- }
-
- function add_nonce( $timestamp, $nonce ) {
- global $wpdb;
- static $nonces_used_this_request = array();
-
- if ( isset( $nonces_used_this_request["$timestamp:$nonce"] ) ) {
- return $nonces_used_this_request["$timestamp:$nonce"];
- }
-
- // This should always have gone through Jetpack_Signature::sign_request() first to check $timestamp an $nonce
- $timestamp = (int) $timestamp;
- $nonce = $wpdb->escape( $nonce );
-
- // Raw query so we can avoid races: add_option will also update
- $show_errors = $wpdb->show_errors( false );
- $return = $wpdb->query( $wpdb->prepare(
- "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s)",
- "jetpack_nonce_{$timestamp}_{$nonce}",
- time(),
- 'no'
- ) );
- $wpdb->show_errors( $show_errors );
-
- $nonces_used_this_request["$timestamp:$nonce"] = $return;
-
- return $return;
- }
-
- /**
- * In some setups, $HTTP_RAW_POST_DATA can be emptied during some IXR_Server paths since it is passed by reference to various methods.
- * Capture it here so we can verify the signature later.
- */
- function xmlrpc_methods( $methods ) {
- $this->HTTP_RAW_POST_DATA = $GLOBALS['HTTP_RAW_POST_DATA'];
- return $methods;
- }
-
- function xmlrpc_options( $options ) {
- $options['jetpack_version'] = array(
- 'desc' => __( 'Jetpack Plugin Version' , 'jetpack'),
- 'readonly' => true,
- 'value' => JETPACK__VERSION,
- );
-
- $options['jetpack_client_id'] = array(
- 'desc' => __( 'The Client ID/WP.com Blog ID of this site' , 'jetpack'),
- 'readonly' => true,
- 'value' => Jetpack::get_option( 'id' ),
- );
- return $options;
- }
-
- public static function clean_nonces( $all = false ) {
- global $wpdb;
-
- $sql = "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE %s";
- $sql_args = array( like_escape( 'jetpack_nonce_' ) . '%' );
-
- if ( true !== $all ) {
- $sql .= ' AND CAST( `option_value` AS UNSIGNED ) < %d';
- $sql_args[] = time() - 3600;
- }
-
- $sql .= ' LIMIT 100';
-
- $sql = $wpdb->prepare( $sql, $sql_args );
-
- for ( $i = 0; $i < 1000; $i++ ) {
- if ( !$wpdb->query( $sql ) ) {
- break;
- }
- }
- }
-
- /**
- * State is passed via cookies from one request to the next, but never to subsequent requests.
- * SET: state( $key, $value );
- * GET: $value = state( $key );
- *
- * @param string $key
- * @param string $value
- * @param bool $restate private
- */
- public static function state( $key = null, $value = null, $restate = false ) {
- static $state = array();
- static $path, $domain;
- if ( !isset( $path ) ) {
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
- $admin_url = Jetpack::admin_url();
- $bits = parse_url( $admin_url );
-
- if ( is_array( $bits ) ) {
- $path = ( isset( $bits['path'] ) ) ? dirname( $bits['path'] ) : null;
- $domain = ( isset( $bits['host'] ) ) ? $bits['host'] : null;
- } else {
- $path = $domain = null;
- }
- }
-
- // Extract state from cookies and delete cookies
- if ( isset( $_COOKIE[ 'jetpackState' ] ) && is_array( $_COOKIE[ 'jetpackState' ] ) ) {
- $yum = $_COOKIE[ 'jetpackState' ];
- unset( $_COOKIE[ 'jetpackState' ] );
- foreach ( $yum as $k => $v ) {
- if ( strlen( $v ) )
- $state[ $k ] = $v;
- setcookie( "jetpackState[$k]", false, 0, $path, $domain );
- }
- }
-
- if ( $restate ) {
- foreach ( $state as $k => $v ) {
- setcookie( "jetpackState[$k]", $v, 0, $path, $domain );
- }
- return;
- }
-
- // Get a state variable
- if ( isset( $key ) && !isset( $value ) ) {
- if ( array_key_exists( $key, $state ) )
- return $state[ $key ];
- return null;
- }
-
- // Set a state variable
- if ( isset ( $key ) && isset( $value ) ) {
- $state[ $key ] = $value;
- setcookie( "jetpackState[$key]", $value, 0, $path, $domain );
- }
- }
-
- public static function restate() {
- Jetpack::state( null, null, true );
- }
-
- public static function check_privacy( $file ) {
- static $is_site_publicly_accessible = null;
-
- if ( is_null( $is_site_publicly_accessible ) ) {
- $is_site_publicly_accessible = false;
-
- Jetpack::load_xml_rpc_client();
- $rpc = new Jetpack_IXR_Client();
-
- $success = $rpc->query( 'jetpack.isSitePubliclyAccessible', home_url() );
- if ( $success ) {
- $response = $rpc->getResponse();
- if ( $response ) {
- $is_site_publicly_accessible = true;
- }
- }
-
- Jetpack::update_option( 'public', (int) $is_site_publicly_accessible );
- }
-
- if ( $is_site_publicly_accessible ) {
- return;
- }
-
- $module_slug = self::get_module_slug( $file );
-
- $privacy_checks = Jetpack::state( 'privacy_checks' );
- if ( !$privacy_checks ) {
- $privacy_checks = $module_slug;
- } else {
- $privacy_checks .= ",$module_slug";
- }
-
- Jetpack::state( 'privacy_checks', $privacy_checks );
- }
-
- /**
- * Helper method for multicall XMLRPC.
- */
- public static function xmlrpc_async_call() {
- global $blog_id;
- static $clients = array();
-
- $client_blog_id = is_multisite() ? $blog_id : 0;
-
- if ( !isset( $clients[$client_blog_id] ) ) {
- Jetpack::load_xml_rpc_client();
- $clients[$client_blog_id] = new Jetpack_IXR_ClientMulticall( array(
- 'user_id' => JETPACK_MASTER_USER,
- ) );
- ignore_user_abort( true );
- add_action( 'shutdown', array( 'Jetpack', 'xmlrpc_async_call' ) );
- }
-
- $args = func_get_args();
-
- if ( !empty( $args[0] ) ) {
- call_user_func_array( array( $clients[$client_blog_id], 'addCall' ), $args );
- } elseif ( is_multisite() ) {
- foreach ( $clients as $client_blog_id => $client ) {
- if ( !$client_blog_id || empty( $client->calls ) ) {
- continue;
- }
-
- $switch_success = switch_to_blog( $client_blog_id, true );
- if ( !$switch_success ) {
- continue;
- }
-
- flush();
- $client->query();
-
- restore_current_blog();
- }
- } else {
- if ( isset( $clients[0] ) && !empty( $clients[0]->calls ) ) {
- flush();
- $clients[0]->query();
- }
- }
- }
-
- public static function staticize_subdomain( $url ) {
- $host = parse_url( $url, PHP_URL_HOST );
- if ( !preg_match( '/.?(?:wordpress|wp)\.com$/', $host ) ) {
- return $url;
- }
-
- if ( is_ssl() ) {
- return preg_replace( '|https?://[^/]++/|', 'https://s-ssl.wordpress.com/', $url );
- }
-
- srand( crc32( basename( $url ) ) );
- $static_counter = rand( 0, 2 );
- srand(); // this resets everything that relies on this, like array_rand() and shuffle()
-
- return preg_replace( '|://[^/]+?/|', "://s$static_counter.wp.com/", $url );
- }
-
-/* JSON API Authorization */
-
- /**
- * Handles the login action for Authorizing the JSON API
- */
- function login_form_json_api_authorization() {
- $this->verify_json_api_authorization_request();
-
- add_action( 'wp_login', array( &$this, 'store_json_api_authorization_token' ), 10, 2 );
-
- add_action( 'login_message', array( &$this, 'login_message_json_api_authorization' ) );
- add_action( 'login_form', array( &$this, 'preserve_action_in_login_form_for_json_api_authorization' ) );
- add_filter( 'site_url', array( &$this, 'post_login_form_to_signed_url' ), 10, 3 );
- }
-
- // Make sure the login form is POSTed to the signed URL so we can reverify the request
- function post_login_form_to_signed_url( $url, $path, $scheme ) {
- if ( 'wp-login.php' !== $path || 'login_post' !== $scheme ) {
- return $url;
- }
-
- return "$url?{$_SERVER['QUERY_STRING']}";
- }
-
- // Make sure the POSTed request is handled by the same action
- function preserve_action_in_login_form_for_json_api_authorization() {
- echo "<input type='hidden' name='action' value='jetpack_json_api_authorization' />\n";
- }
-
- // If someone logs in to approve API access, store the Access Code in usermeta
- function store_json_api_authorization_token( $user_login, $user ) {
- add_filter( 'login_redirect', array( &$this, 'add_token_to_login_redirect_json_api_authorization' ), 10, 3 );
- add_filter( 'allowed_redirect_hosts', array( &$this, 'allow_wpcom_public_api_domain' ) );
- $token = wp_generate_password( 32, false );
- update_user_meta( $user->ID, 'jetpack_json_api_' . $this->json_api_authorization_request['client_id'], $token );
- }
-
- // Add public-api.wordpress.com to the safe redirect whitelist - only added when someone allows API access
- function allow_wpcom_public_api_domain( $domains ) {
- $domains[] = 'public-api.wordpress.com';
- return $domains;
- }
-
- // Add the Access Code details to the public-api.wordpress.com redirect
- function add_token_to_login_redirect_json_api_authorization( $redirect_to, $original_redirect_to, $user ) {
- return add_query_arg( urlencode_deep( array(
- 'jetpack-code' => get_user_meta( $user->ID, 'jetpack_json_api_' . $this->json_api_authorization_request['client_id'], true ),
- 'jetpack-user-id' => (int) $user->ID,
- 'jetpack-state' => $this->json_api_authorization_request['state'],
- ) ), $redirect_to );
- }
-
- // Verifies the request by checking the signature
- function verify_json_api_authorization_request() {
- require_once dirname( __FILE__ ) . '/class.jetpack-signature.php';
-
- $token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
- if ( !$token || empty( $token->secret ) ) {
- wp_die( __( 'You must connect your Jetpack plugin to WordPress.com to use this feature.' , 'jetpack') );
- }
-
- $die_error = __( 'Someone may be trying to trick you into giving them access to your site. Or it could be you just encountered a bug :). Either way, please close this window.', 'jetpack' );
-
- $jetpack_signature = new Jetpack_Signature( $token->secret, (int) Jetpack::get_option( 'time_diff' ) );
- $signature = $jetpack_signature->sign_current_request( array( 'body' => null, 'method' => 'GET' ) );
- if ( !$signature ) {
- wp_die( $die_error );
- } else if ( is_wp_error( $signature ) ) {
- wp_die( $die_error );
- } else if ( $signature !== $_GET['signature'] ) {
- if ( is_ssl() ) {
- // If we signed an HTTP request on the Jetpack Servers, but got redirected to HTTPS by the local blog, check the HTTP signature as well
- $signature = $jetpack_signature->sign_current_request( array( 'scheme' => 'http', 'body' => null, 'method' => 'GET' ) );
- if ( !$signature || is_wp_error( $signature ) || $signature !== $_GET['signature'] ) {
- wp_die( $die_error );
- }
- } else {
- wp_die( $die_error );
- }
- }
-
- $timestamp = (int) $_GET['timestamp'];
- $nonce = stripslashes( (string) $_GET['nonce'] );
-
- if ( !$this->add_nonce( $timestamp, $nonce ) ) {
- // De-nonce the nonce, at least for 5 minutes.
- // We have to reuse this nonce at least once (used the first time when the initial request is made, used a second time when the login form is POSTed)
- $old_nonce_time = get_option( "jetpack_nonce_{$timestamp}_{$nonce}" );
- if ( $old_nonce_time < time() - 300 ) {
- wp_die( __( 'The authorization process expired. Please go back and try again.' , 'jetpack') );
- }
- }
-
- $data = json_decode( base64_decode( stripslashes( $_GET['data'] ) ) );
- $data_filters = array(
- 'state' => 'opaque',
- 'client_id' => 'int',
- 'client_title' => 'string',
- 'client_image' => 'url',
- );
-
- foreach ( $data_filters as $key => $sanitation ) {
- if ( !isset( $data->$key ) ) {
- wp_die( $die_error );
- }
-
- switch ( $sanitation ) {
- case 'int' :
- $this->json_api_authorization_request[$key] = (int) $data->$key;
- break;
- case 'opaque' :
- $this->json_api_authorization_request[$key] = (string) $data->$key;
- break;
- case 'string' :
- $this->json_api_authorization_request[$key] = wp_kses( (string) $data->$key, array() );
- break;
- case 'url' :
- $this->json_api_authorization_request[$key] = esc_url_raw( (string) $data->$key );
- break;
- }
- }
-
- if ( empty( $this->json_api_authorization_request['client_id'] ) ) {
- wp_die( $die_error );
- }
- }
-
- function login_message_json_api_authorization( $message ) {
- return '<p class="message">' . sprintf(
- esc_html__( '%s wants to access your site&#8217;s data. Log in to authorize that access.' , 'jetpack'),
- '<strong>' . esc_html( $this->json_api_authorization_request['client_title'] ) . '</strong>'
- ) . '<img src="' . esc_url( $this->json_api_authorization_request['client_image'] ) . '" /></p>';
- }
-}
-
-class Jetpack_Client {
- /**
- * Makes an authorized remote request using Jetpack_Signature
- *
- * @return array|WP_Error WP HTTP response on success
- */
- public static function remote_request( $args, $body = null ) {
- $defaults = array(
- 'url' => '',
- 'user_id' => 0,
- 'blog_id' => 0,
- 'auth_location' => JETPACK_CLIENT__AUTH_LOCATION,
- 'method' => 'POST',
- 'timeout' => 10,
- 'redirection' => 0,
- );
-
- $args = wp_parse_args( $args, $defaults );
-
- $args['blog_id'] = (int) $args['blog_id'];
-
- if ( 'header' != $args['auth_location'] ) {
- $args['auth_location'] = 'query_string';
- }
-
- $token = Jetpack_Data::get_access_token( $args['user_id'] );
- if ( !$token ) {
- return new Jetpack_Error( 'missing_token' );
- }
-
- $method = strtoupper( $args['method'] );
-
- $timeout = intval( $args['timeout'] );
-
- $redirection = $args['redirection'];
-
- $request = compact( 'method', 'body', 'timeout', 'redirection' );
-
- @list( $token_key, $secret ) = explode( '.', $token->secret );
- if ( empty( $token ) || empty( $secret ) ) {
- return new Jetpack_Error( 'malformed_token' );
- }
-
- $token_key = sprintf( '%s:%d:%d', $token_key, JETPACK__API_VERSION, $token->external_user_id );
-
- require_once dirname( __FILE__ ) . '/class.jetpack-signature.php';
-
- $time_diff = (int) Jetpack::get_option( 'time_diff' );
- $jetpack_signature = new Jetpack_Signature( $token->secret, $time_diff );
-
- $timestamp = time() + $time_diff;
- $nonce = wp_generate_password( 10, false );
-
- // Kind of annoying. Maybe refactor Jetpack_Signature to handle body-hashing
- if ( is_null( $body ) ) {
- $body_hash = '';
- } else {
- if ( !is_string( $body ) ) {
- return new Jetpack_Error( 'invalid_body', 'Body is malformed.' );
- }
- $body_hash = jetpack_sha1_base64( $body );
- }
-
- $auth = array(
- 'token' => $token_key,
- 'timestamp' => $timestamp,
- 'nonce' => $nonce,
- 'body-hash' => $body_hash,
- );
-
- if ( false !== strpos( $args['url'], 'xmlrpc.php' ) ) {
- $url_args = array( 'for' => 'jetpack' );
- } else {
- $url_args = array();
- }
-
- if ( 'header' != $args['auth_location'] ) {
- $url_args += $auth;
- }
-
- $url = add_query_arg( urlencode_deep( $url_args ), $args['url'] );
- $url = Jetpack::fix_url_for_bad_hosts( $url, $request );
-
- $signature = $jetpack_signature->sign_request( $token_key, $timestamp, $nonce, $body_hash, $method, $url, $body, false );
-
- if ( !$signature || is_wp_error( $signature ) ) {
- return $signature;
- }
-
- // Send an Authorization header so various caches/proxies do the right thing
- $auth['signature'] = $signature;
- $auth['version'] = JETPACK__VERSION;
- $header_pieces = array();
- foreach ( $auth as $key => $value ) {
- $header_pieces[] = sprintf( '%s="%s"', $key, $value );
- }
- $request['headers'] = array(
- 'Authorization' => "X_JETPACK " . join( ' ', $header_pieces ),
- );
-
- if ( 'header' != $args['auth_location'] ) {
- $url = add_query_arg( 'signature', urlencode( $signature ), $url );
- }
-
- return Jetpack_Client::_wp_remote_request( $url, $request );
- }
-
- /**
- * Wrapper for wp_remote_request(). Turns off SSL verification for certain SSL errors.
- * This is lame, but many, many, many hosts have misconfigured SSL.
- *
- * When Jetpack is registered, the jetpack_fallback_no_verify_ssl_certs option is set to the current time if:
- * 1. a certificate error is found AND
- * 2. not verifying the certificate works around the problem.
- *
- * The option is checked on each request.
- *
- * @internal
- * @todo: Better fallbacks (bundled certs?), feedback, UI, ....
- * @see Jetpack::fix_url_for_bad_hosts()
- *
- * @return array|WP_Error WP HTTP response on success
- */
- public static function _wp_remote_request( $url, $args, $set_fallback = false ) {
- $fallback = Jetpack::get_option( 'fallback_no_verify_ssl_certs' );
- if ( false === $fallback ) {
- Jetpack::update_option( 'fallback_no_verify_ssl_certs', 0 );
- }
-
- if ( (int) $fallback ) {
- // We're flagged to fallback
- $args['sslverify'] = false;
- }
-
- $response = wp_remote_request( $url, $args );
-
- if (
- !$set_fallback // We're not allowed to set the flag on this request, so whatever happens happens
- ||
- isset( $args['sslverify'] ) && !$args['sslverify'] // No verification - no point in doing it again
- ||
- !is_wp_error( $response ) // Let it ride
- ) {
- Jetpack_Client::set_time_diff( $response, $set_fallback );
- return $response;
- }
-
- // At this point, we're not flagged to fallback and we are allowed to set the flag on this request.
-
- $message = $response->get_error_message();
-
- // Is it an SSL Certificate verification error?
- if (
- false === strpos( $message, '14090086' ) // OpenSSL SSL3 certificate error
- &&
- false === strpos( $message, '1407E086' ) // OpenSSL SSL2 certificate error
- &&
- false === strpos( $message, 'error setting certificate verify locations' ) // cURL CA bundle not found
- &&
- false === strpos( $message, 'Peer certificate cannot be authenticated with' ) // cURL CURLE_SSL_CACERT: CA bundle found, but not helpful
- // different versions of curl have different error messages
- // this string should catch them all
- &&
- false === strpos( $message, 'Problem with the SSL CA cert' ) // cURL CURLE_SSL_CACERT_BADFILE: probably access rights
- ) {
- // No, it is not.
- return $response;
- }
-
- // Redo the request without SSL certificate verification.
- $args['sslverify'] = false;
- $response = wp_remote_request( $url, $args );
-
- if ( !is_wp_error( $response ) ) {
- // The request went through this time, flag for future fallbacks
- Jetpack::update_option( 'fallback_no_verify_ssl_certs', time() );
- Jetpack_Client::set_time_diff( $response, $set_fallback );
- }
-
- return $response;
- }
-
- public static function set_time_diff( &$response, $force_set = false ) {
- $code = wp_remote_retrieve_response_code( $response );
-
- // Only trust the Date header on some responses
- if ( 200 != $code && 304 != $code && 400 != $code && 401 != $code ) {
- return;
- }
-
- if ( !$date = wp_remote_retrieve_header( $response, 'date' ) ) {
- return;
- }
-
- if ( 0 >= $time = (int) strtotime( $date ) ) {
- return;
- }
-
- $time_diff = $time - time();
-
- if ( $force_set ) { // during register
- Jetpack::update_option( 'time_diff', $time_diff );
- } else { // otherwise
- $old_diff = Jetpack::get_option( 'time_diff' );
- if ( false === $old_diff || abs( $time_diff - (int) $old_diff ) > 10 ) {
- Jetpack::update_option( 'time_diff', $time_diff );
- }
- }
- }
-}
-
-class Jetpack_Data {
- /**
- * Gets locally stored token
- *
- * @return object|false
- */
- public static function get_access_token( $user_id = false ) {
- if ( $user_id ) {
- if ( !$tokens = Jetpack::get_option( 'user_tokens' ) ) {
- return false;
- }
- if ( $user_id === JETPACK_MASTER_USER ) {
- if ( !$user_id = Jetpack::get_option( 'master_user' ) ) {
- return false;
- }
- }
- if ( !isset( $tokens[$user_id] ) || !$token = $tokens[$user_id] ) {
- return false;
- }
- $token_chunks = explode( '.', $token );
- if ( empty( $token_chunks[1] ) || empty( $token_chunks[2] ) ) {
- return false;
- }
- if ( $user_id != $token_chunks[2] ) {
- return false;
- }
- $token = "{$token_chunks[0]}.{$token_chunks[1]}";
- } else {
- $token = Jetpack::get_option( 'blog_token' );
- if ( empty( $token ) ) {
- return false;
- }
- }
-
- return (object) array(
- 'secret' => $token,
- 'external_user_id' => (int) $user_id,
- );
- }
-}
-
-/**
- * Client = Plugin
- * Client Server = API Methods the Plugin must respond to
- *
- * @todo Roll this into Jetpack? There's only one 'public' method now: ::authorize().
- */
-class Jetpack_Client_Server {
- function authorize() {
- $data = stripslashes_deep( $_GET );
-
- $args = array();
-
- $redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : '';
-
- do {
- $jetpack = Jetpack::init();
- $role = $jetpack->translate_current_user_to_role();
- if ( !$role ) {
- Jetpack::state( 'error', 'no_role' );
- break;
- }
-
- $cap = $jetpack->translate_role_to_cap( $role );
- if ( !$cap ) {
- Jetpack::state( 'error', 'no_cap' );
- break;
- }
-
- check_admin_referer( "jetpack-authorize_{$role}_{$redirect}" );
-
- if ( !empty( $data['error'] ) ) {
- Jetpack::state( 'error', $data['error'] );
- break;
- }
-
- if ( empty( $data['state'] ) ) {
- Jetpack::state( 'error', 'no_state' );
- break;
- }
-
- if ( !ctype_digit( $data['state'] ) ) {
- Jetpack::state( 'error', 'invalid_state' );
- break;
- }
-
- $current_user_id = get_current_user_id();
- if ( $current_user_id != $data['state'] ) {
- Jetpack::state( 'error', 'wrong_state' );
- break;
- }
-
- if ( empty( $data['code'] ) ) {
- Jetpack::state( 'error', 'no_code' );
- break;
- }
-
- $token = $this->get_token( $data );
-
- if ( is_wp_error( $token ) ) {
- if ( $error = $token->get_error_code() )
- Jetpack::state( 'error', $error );
- else
- Jetpack::state( 'error', 'invalid_token' );
-
- Jetpack::state( 'error_description', $token->get_error_message() );
-
- break;
- }
-
- if ( !$token ) {
- Jetpack::state( 'error', 'no_token' );
- break;
- }
-
- $is_master_user = ! Jetpack::is_active();
-
- Jetpack::update_user_token( $current_user_id, sprintf( '%s.%d', $token, $current_user_id ), $is_master_user );
-
-
- if ( $is_master_user ) {
- Jetpack::state( 'message', 'authorized' );
- } else {
- Jetpack::state( 'message', 'linked' );
- // Don't activate anything since we are just connecting a user.
- break;
- }
-
- if ( $active_modules = Jetpack::get_option( 'active_modules' ) ) {
- Jetpack::delete_option( 'active_modules' );
-
- Jetpack::activate_default_modules( 999, 1, $active_modules );
- } else {
- Jetpack::activate_default_modules();
- }
-
- $jetpack->sync->register( 'noop' ); // Spawn a sync to make sure the Jetpack Servers know what modules are active.
-
- // Start nonce cleaner
- wp_clear_scheduled_hook( 'jetpack_clean_nonces' );
- wp_schedule_event( time(), 'hourly', 'jetpack_clean_nonces' );
- } while ( false );
-
- if ( wp_validate_redirect( $redirect ) ) {
- wp_safe_redirect( $redirect );
- } else {
- wp_safe_redirect( Jetpack::admin_url() );
- }
-
- exit;
- }
-
- public static function deactivate_plugin( $probable_file, $probable_title ) {
- if ( is_plugin_active( $probable_file ) ) {
- deactivate_plugins( $probable_file );
- return 1;
- } else {
- // If the plugin is not in the usual place, try looking through all active plugins.
- $active_plugins = get_option( 'active_plugins', array() );
- foreach ( $active_plugins as $plugin ) {
- $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
- if ( $data['Name'] == $probable_title ) {
- deactivate_plugins( $plugin );
- return 1;
- }
- }
- }
-
- return 0;
- }
-
- /**
- * @return object|WP_Error
- */
- function get_token( $data ) {
- $jetpack = Jetpack::init();
- $role = $jetpack->translate_current_user_to_role();
-
- if ( !$role ) {
- return new Jetpack_Error( 'role', __( 'An administrator for this blog must set up the Jetpack connection.', 'jetpack' ) );
- }
-
- $client_secret = Jetpack_Data::get_access_token();
- if ( !$client_secret ) {
- return new Jetpack_Error( 'client_secret', __( 'You need to register your Jetpack before connecting it.', 'jetpack' ) );
- }
-
- $redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : '';
-
- $body = array(
- 'client_id' => Jetpack::get_option( 'id' ),
- 'client_secret' => $client_secret->secret,
- 'grant_type' => 'authorization_code',
- 'code' => $data['code'],
- 'redirect_uri' => add_query_arg( array(
- 'action' => 'authorize',
- '_wpnonce' => wp_create_nonce( "jetpack-authorize_{$role}_{$redirect}" ),
- 'redirect' => $redirect ? urlencode( $redirect ) : false,
- ), menu_page_url( 'jetpack', false ) ),
- );
-
- $args = array(
- 'method' => 'POST',
- 'body' => $body,
- 'headers' => array(
- 'Accept' => 'application/json',
- ),
- );
- $response = Jetpack_Client::_wp_remote_request( Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'token' ), $args ), $args );
-
- if ( is_wp_error( $response ) ) {
- return new Jetpack_Error( 'token_http_request_failed', $response->get_error_message() );
- }
-
- $code = wp_remote_retrieve_response_code( $response );
- $entity = wp_remote_retrieve_body( $response );
-
- if ( $entity )
- $json = json_decode( $entity );
- else
- $json = false;
-
- if ( 200 != $code || !empty( $json->error ) ) {
- if ( empty( $json->error ) )
- return new Jetpack_Error( 'unknown', '', $code );
-
- $error_description = isset( $json->error_description ) ? sprintf( __( 'Error Details: %s', 'jetpack' ), (string) $json->error_description ) : '';
-
- return new Jetpack_Error( (string) $json->error, $error_description, $code );
- }
-
- if ( empty( $json->access_token ) || !is_scalar( $json->access_token ) ) {
- return new Jetpack_Error( 'access_token', '', $code );
- }
-
- if ( empty( $json->token_type ) || 'X_JETPACK' != strtoupper( $json->token_type ) ) {
- return new Jetpack_Error( 'token_type', '', $code );
- }
-
- if ( empty( $json->scope ) ) {
- return new Jetpack_Error( 'scope', 'No Scope', $code );
- }
- @list( $role, $hmac ) = explode( ':', $json->scope );
- if ( empty( $role ) || empty( $hmac ) ) {
- return new Jetpack_Error( 'scope', 'Malformed Scope', $code );
- }
- if ( $jetpack->sign_role( $role ) !== $json->scope ) {
- return new Jetpack_Error( 'scope', 'Invalid Scope', $code );
- }
-
- if ( !$cap = $jetpack->translate_role_to_cap( $role ) )
- return new Jetpack_Error( 'scope', 'No Cap', $code );
- if ( !current_user_can( $cap ) )
- return new Jetpack_Error( 'scope', 'current_user_cannot', $code );
-
- return (string) $json->access_token;
- }
-}
-
-
-/**
- * Request that a piece of data on this WordPress install be synced back to the
- * Jetpack server for remote processing/notifications/etc
- */
-class Jetpack_Sync {
- // What modules want to sync what content
- var $sync_conditions = array( 'posts' => array(), 'comments' => array() );
-
- // We keep track of all the options registered for sync so that we can sync them all if needed
- var $sync_options = array();
-
- // Keep trac of status transitions, which we wouldn't always know about on the Jetpack Servers but are important when deciding what to do with the sync.
- var $post_transitions = array();
- var $comment_transitions = array();
-
- // Objects to sync
- var $sync = array();
-
- function __construct() {
- // WP Cron action. Only used on upgrade
- add_action( 'jetpack_sync_all_registered_options', array( $this, 'sync_all_registered_options' ) );
- }
-
-/* Static Methods for Modules */
-
- /**
- * @param string $file __FILE__
- * @param array settings:
- * post_types => array( post_type slugs ): The post types to sync. Default: post, page
- * post_stati => array( post_status slugs ): The post stati to sync. Default: publish
- */
- static function sync_posts( $file, array $settings = null ) {
- $jetpack = Jetpack::init();
- $args = func_get_args();
- return call_user_func_array( array( $jetpack->sync, 'posts' ), $args );
- }
-
- /**
- * @param string $file __FILE__
- * @param array settings:
- * post_types => array( post_type slugs ): The post types to sync. Default: post, page
- * post_stati => array( post_status slugs ): The post stati to sync. Default: publish
- * comment_types => array( comment_type slugs ): The comment types to sync. Default: '', comment, trackback, pingback
- * comment_stati => array( comment_status slugs ): The comment stati to sync. Default: approved
- */
- static function sync_comments( $file, array $settings = null ) {
- $jetpack = Jetpack::init();
- $args = func_get_args();
- return call_user_func_array( array( $jetpack->sync, 'comments' ), $args );
- }
-
- /**
- * @param string $file __FILE__
- * @param string $option, Option name to sync
- * @param string $option ...
- */
- static function sync_options( $file, $option /*, $option, ... */ ) {
- $jetpack = Jetpack::init();
- $args = func_get_args();
- return call_user_func_array( array( $jetpack->sync, 'options' ), $args );
- }
-
-/* Internal Methods */
-
- /**
- * Create a sync object/request
- *
- * @param string $object Type of object to sync -- [ post | comment | option ]
- * @param int $id Unique identifier
- * @param array $settings
- */
- function register( $object, $id = false, array $settings = null ) {
- // Since we've registered something for sync, hook it up to execute on shutdown if we haven't already
- if ( !$this->sync ) {
- ignore_user_abort( true );
- add_action( 'shutdown', array( $this, 'sync' ), 9 ); // Right before async XML-RPC
- }
-
- $defaults = array(
- 'on_behalf_of' => array(), // What modules want this data
- );
- $settings = wp_parse_args( $settings, $defaults );
-
- if ( !isset( $this->sync[$object] ) ) {
- $this->sync[$object] = array();
- }
-
- // Store the settings for this object
- if (
- // First time for this object
- !isset( $this->sync[$object][$id] )
- ) {
- // Easy: store the current settings
- $this->sync[$object][$id] = $settings;
- } else {
- // Not as easy: we have to manually merge the settings from previous runs for this object with the settings for this run
-
- $this->sync[$object][$id]['on_behalf_of'] = array_unique( array_merge( $this->sync[$object][$id]['on_behalf_of'], $settings['on_behalf_of'] ) );
- }
-
- $delete_prefix = 'delete_';
- if ( 0 === strpos( $object, $delete_prefix ) ) {
- $unset_object = substr( $object, strlen( $delete_prefix ) );
- } else {
- $unset_object = "{$delete_prefix}{$object}";
- }
-
- // Ensure post ... delete_post yields a delete operation
- // Ensure delete_post ... post yields a sync post operation
- // Ensure update_option() ... delete_option() ends up as a delete
- // Ensure delete_option() ... update_option() ends up as an update
- // Etc.
- unset( $this->sync[$unset_object][$id] );
-
- return true;
- }
-
- function get_common_sync_data() {
- $available_modules = Jetpack::get_available_modules();
- $active_modules = Jetpack::get_active_modules();
- $modules = array();
- foreach ( $available_modules as $available_module ) {
- $modules[$available_module] = in_array( $available_module, $active_modules );
- }
- $modules['vaultpress'] = class_exists( 'VaultPress' ) || function_exists( 'vaultpress_contact_service' );
-
- $sync_data = array(
- 'modules' => $modules,
- 'version' => JETPACK__VERSION,
- );
-
- return $sync_data;
- }
-
- /**
- * Set up all the data and queue it for the outgoing XML-RPC request
- */
- function sync() {
- if ( !$this->sync ) {
- return false;
- }
-
- $sync_data = $this->get_common_sync_data();
-
- $wp_importing = defined( 'WP_IMPORTING' ) && WP_IMPORTING;
-
- foreach ( $this->sync as $sync_operation_type => $sync_operations ) {
- switch ( $sync_operation_type ) {
- case 'post':
- if ( $wp_importing ) {
- break;
- }
-
- $global_post = isset( $GLOBALS['post'] ) ? $GLOBALS['post'] : null;
- $GLOBALS['post'] = null;
- foreach ( $sync_operations as $post_id => $settings ) {
- $sync_data['post'][$post_id] = $this->get_post( $post_id );
- if ( isset( $this->post_transitions[$post_id] ) ) {
- $sync_data['post'][$post_id]['transitions'] = $this->post_transitions[$post_id];
- } else {
- $sync_data['post'][$post_id]['transitions'] = array( false, false );
- }
- $sync_data['post'][$post_id]['on_behalf_of'] = $settings['on_behalf_of'];
- }
- $GLOBALS['post'] = $global_post;
- unset( $global_post );
- break;
- case 'comment':
- if ( $wp_importing ) {
- break;
- }
-
- $global_comment = isset( $GLOBALS['comment'] ) ? $GLOBALS['comment'] : null;
- unset( $GLOBALS['comment'] );
- foreach ( $sync_operations as $comment_id => $settings ) {
- $sync_data['comment'][$comment_id] = $this->get_comment( $comment_id );
- if ( isset( $this->comment_transitions[$comment_id] ) ) {
- $sync_data['comment'][$comment_id]['transitions'] = $this->comment_transitions[$comment_id];
- } else {
- $sync_data['comment'][$comment_id]['transitions'] = array( false, false );
- }
- $sync_data['comment'][$comment_id]['on_behalf_of'] = $settings['on_behalf_of'];
- }
- $GLOBALS['comment'] = $global_comment;
- unset( $global_comment );
- break;
- case 'option' :
- foreach ( $sync_operations as $option => $settings ) {
- $sync_data['option'][$option] = array( 'value' => get_option( $option ) );
- }
- break;
-
- case 'delete_post':
- case 'delete_comment':
- foreach ( $sync_operations as $object_id => $settings ) {
- $sync_data[$sync_operation_type][$object_id] = array( 'on_behalf_of' => $settings['on_behalf_of'] );
- }
- break;
- case 'delete_option' :
- foreach ( $sync_operations as $object_id => $settings ) {
- $sync_data[$sync_operation_type][$object_id] = true;
- }
- break;
- }
- }
-
- Jetpack::xmlrpc_async_call( 'jetpack.syncContent', $sync_data );
- }
-
- /**
- * Format and return content data from a direct xmlrpc request for it.
- *
- * @param array $content_ids: array( 'posts' => array of ids, 'comments' => array of ids, 'options' => array of options )
- */
- function get_content( $content_ids ) {
- $sync_data = $this->get_common_sync_data();
-
- if ( isset( $content_ids['posts'] ) ) {
- foreach ( $content_ids['posts'] as $id ) {
- $sync_data['post'][$id] = $this->get_post( $id );
- }
- }
-
- if ( isset( $content_ids['comments'] ) ) {
- foreach ( $content_ids['comments'] as $id ) {
- $sync_data['comment'][$id] = $this->get_post( $id );
- }
- }
-
- if ( isset( $content_ids['options'] ) ) {
- foreach ( $content_ids['options'] as $option ) {
- $sync_data['option'][$option] = array( 'value' => get_option( $option ) );
- }
- }
-
- return $sync_data;
- }
-
- /**
- * Helper method for registering a post for sync
- *
- * @param int $id wp_posts.ID
- * @param array $settings Sync data
- */
- function register_post( $id, array $settings = null ) {
- $id = (int) $id;
- if ( !$id ) {
- return false;
- }
-
- $post = get_post( $id );
- if ( !$post ) {
- return false;
- }
-
- $settings = wp_parse_args( $settings, array(
- 'on_behalf_of' => array(),
- ) );
-
- return $this->register( 'post', $id, $settings );
- }
-
- /**
- * Helper method for registering a comment for sync
- *
- * @param int $id wp_comments.comment_ID
- * @param array $settings Sync data
- */
- function register_comment( $id, array $settings = null ) {
- $id = (int) $id;
- if ( !$id ) {
- return false;
- }
-
- $comment = get_comment( $id );
- if ( !$comment || empty( $comment->comment_post_ID ) ) {
- return false;
- }
-
- $post = get_post( $comment->comment_post_ID );
- if ( !$post ) {
- return false;
- }
-
- $settings = wp_parse_args( $settings, array(
- 'on_behalf_of' => array(),
- ) );
-
- return $this->register( 'comment', $id, $settings );
- }
-
-/* Posts Sync */
-
- function posts( $file, array $settings = null ) {
- $module_slug = Jetpack::get_module_slug( $file );
-
- $defaults = array(
- 'post_types' => array( 'post', 'page' ),
- 'post_stati' => array( 'publish' ),
- );
-
- $this->sync_conditions['posts'][$module_slug] = wp_parse_args( $settings, $defaults );
-
- add_action( 'transition_post_status', array( $this, 'transition_post_status_action' ), 10, 3 );
- add_action( 'delete_post', array( $this, 'delete_post_action' ) );
- }
-
- function delete_post_action( $post_id ) {
- $post = get_post( $post_id );
- if ( !$post ) {
- return $this->register( 'delete_post', (int) $post_id );
- }
-
- $this->transition_post_status_action( 'delete', $post->post_status, $post );
- }
-
- function transition_post_status_action( $new_status, $old_status, $post ) {
- $sync = $this->get_post_sync_operation( $new_status, $old_status, $post, $this->sync_conditions['posts'] );
- if ( !$sync ) {
- // No module wants to sync this post
- return false;
- }
-
- // Track post transitions
- if ( isset( $this->post_transitions[$post->ID] ) ) {
- // status changed more than once - keep tha most recent $new_status
- $this->post_transitions[$post->ID][0] = $new_status;
- } else {
- $this->post_transitions[$post->ID] = array( $new_status, $old_status );
- }
-
- $operation = $sync['operation'];
- unset( $sync['operation'] );
-
- switch ( $operation ) {
- case 'delete' :
- return $this->register( 'delete_post', (int) $post->ID, $sync );
- case 'submit' :
- return $this->register_post( (int) $post->ID, $sync );
- }
- }
-
- function get_post_sync_operation( $new_status, $old_status, $post, $module_conditions ) {
- $delete_on_behalf_of = array();
- $submit_on_behalf_of = array();
- $delete_stati = array( 'delete' );
-
- foreach ( $module_conditions as $module => $conditions ) {
- if ( !in_array( $post->post_type, $conditions['post_types'] ) ) {
- continue;
- }
-
- $deleted_post = in_array( $new_status, $delete_stati );
-
- if ( $deleted_post ) {
- $delete_on_behalf_of[] = $module;
- } else {
- clean_post_cache( $post->ID );
- $new_status = get_post_status( $post->ID ); // Inherited status is resolved here
- }
-
- $old_status_in_stati = in_array( $old_status, $conditions['post_stati'] );
- $new_status_in_stati = in_array( $new_status, $conditions['post_stati'] );
-
- if ( $old_status_in_stati && !$new_status_in_stati ) {
- // Jetpack no longer needs the post
- if ( !$deleted_post ) {
- $delete_on_behalf_of[] = $module;
- } // else, we've already flagged it above
- continue;
- }
-
- if ( !$new_status_in_stati ) {
- continue;
- }
-
- // At this point, we know we want to sync the post, not delete it
- $submit_on_behalf_of[] = $module;
- }
-
- if ( !empty( $submit_on_behalf_of ) ) {
- return array( 'operation' => 'submit', 'on_behalf_of' => $submit_on_behalf_of );
- }
-
- if ( !empty( $delete_on_behalf_of ) ) {
- return array( 'operation' => 'delete', 'on_behalf_of' => $delete_on_behalf_of );
- }
-
- return false;
- }
-
- /**
- * Get a post and associated data in the standard JP format.
- * Cannot be called statically
- *
- * @param int $id Post ID
- * @return Array containing full post details
- */
- function get_post( $id ) {
- $post_obj = get_post( $id );
- if ( !$post_obj )
- return false;
-
- if ( is_callable( $post_obj, 'to_array' ) ) {
- // WP >= 3.5
- $post = $post_obj->to_array();
- } else {
- // WP < 3.5
- $post = get_object_vars( $post_obj );
- }
-
- if ( 0 < strlen( $post['post_password'] ) ) {
- $post['post_password'] = 'auto-' . wp_generate_password( 10, false ); // We don't want the real password. Just pass something random.
- }
-
- // local optimizations
- unset(
- $post['filter'],
- $post['ancestors'],
- $post['post_content_filtered'],
- $post['to_ping'],
- $post['pinged']
- );
-
- if ( $this->is_post_public( $post ) ) {
- $post['post_is_public'] = Jetpack::get_option( 'public' );
- } else {
- //obscure content
- $post['post_content'] = '';
- $post['post_excerpt'] = '';
- $post['post_is_public'] = false;
- }
- $post_type_obj = get_post_type_object( $post['post_type'] );
- $post['post_is_excluded_from_search'] = $post_type_obj->exclude_from_search;
-
- $post['tax'] = array();
- $taxonomies = get_object_taxonomies( $post_obj );
- foreach ( $taxonomies as $taxonomy ) {
- $terms = get_object_term_cache( $post_obj->ID, $taxonomy );
- if ( empty( $terms ) )
- $terms = wp_get_object_terms( $post_obj->ID, $taxonomy );
- $term_names = array();
- foreach ( $terms as $term ) {
- $term_names[] = $term->name;
- }
- $post['tax'][$taxonomy] = $term_names;
- }
-
- $meta = get_post_meta( $post_obj->ID, false );
- $post['meta'] = array();
- foreach ( $meta as $key => $value ) {
- $post['meta'][$key] = array_map( 'maybe_unserialize', $value );
- }
-
- $post['extra'] = array(
- 'author' => get_the_author_meta( 'display_name', $post_obj->post_author ),
- 'author_email' => get_the_author_meta( 'email', $post_obj->post_author ),
- );
-
- if ( $fid = get_post_thumbnail_id( $id ) ) {
- $feature = wp_get_attachment_image_src( $fid, 'large' );
- if ( !empty( $feature[0] ) )
- $post['extra']['featured_image'] = $feature[0];
- }
-
- $post['permalink'] = get_permalink( $post_obj->ID );
- $post['shortlink'] = wp_get_shortlink( $post_obj->ID );
- return $post;
- }
-
- /**
- * Decide whether a post/page/attachment is visible to the public.
- *
- * @param array $post
- * @return bool
- */
- function is_post_public( $post ) {
- if ( !is_array( $post ) ) {
- $post = (array) $post;
- }
-
- if ( 0 < strlen( $post['post_password'] ) )
- return false;
- if ( ! in_array( $post['post_type'], get_post_types( array( 'public' => true ) ) ) )
- return false;
- $post_status = get_post_status( $post['ID'] ); // Inherited status is resolved here.
- if ( ! in_array( $post_status, get_post_stati( array( 'public' => true ) ) ) )
- return false;
- return true;
- }
-
-/* Comments Sync */
-
- function comments( $file, array $settings = null ) {
- $module_slug = Jetpack::get_module_slug( $file );
-
- $defaults = array(
- 'post_types' => array( 'post', 'page' ), // For what post types will we sync comments?
- 'post_stati' => array( 'publish' ), // For what post stati will we sync comments?
- 'comment_types' => array( '', 'comment', 'trackback', 'pingback' ), // What comment types will we sync?
- 'comment_stati' => array( 'approved' ), // What comment stati will we sync?
- );
-
- $settings = wp_parse_args( $settings, $defaults );
-
- $this->sync_conditions['comments'][$module_slug] = $settings;
-
- add_action( 'wp_insert_comment', array( $this, 'wp_insert_comment_action' ), 10, 2 );
- add_action( 'transition_comment_status', array( $this, 'transition_comment_status_action' ), 10, 3 );
- add_action( 'edit_comment', array( $this, 'edit_comment_action' ) );
- }
-
- /*
- * This is really annoying. If you edit a comment, but don't change the status, WordPress doesn't fire the transition_comment_status hook.
- * That means we have to catch these comments on the edit_comment hook, but ignore comments on that hook when the transition_comment_status does fire.
- */
- function edit_comment_action( $comment_id ) {
- $comment = get_comment( $comment_id );
- $new_status = $this->translate_comment_status( $comment->comment_approved );
- add_action( "comment_{$new_status}_{$comment->comment_type}", array( $this, 'transition_comment_status_for_comments_whose_status_does_not_change' ), 10, 2 );
- }
-
- function wp_insert_comment_action( $comment_id, $comment ) {
- $this->transition_comment_status_action( $comment->comment_approved, 'new', $comment );
- }
-
- function transition_comment_status_for_comments_whose_status_does_not_change( $comment_id, $comment ) {
- if ( isset( $this->comment_transitions[$comment_id] ) ) {
- return $this->transition_comment_status_action( $comment->comment_approved, $this->comment_transitions[$comment_id][1], $comment );
- }
-
- return $this->transition_comment_status_action( $comment->comment_approved, $comment->comment_approved, $comment );
- }
-
- function translate_comment_status( $status ) {
- switch ( (string) $status ) {
- case '0' :
- case 'hold' :
- return 'unapproved';
- case '1' :
- case 'approve' :
- return 'approved';
- }
-
- return $status;
- }
-
- function transition_comment_status_action( $new_status, $old_status, $comment ) {
- $post = get_post( $comment->comment_post_ID );
- if ( !$post ) {
- return false;
- }
-
- foreach ( array( 'new_status', 'old_status' ) as $_status ) {
- $$_status = $this->translate_comment_status( $$_status );
- }
-
- // Track comment transitions
- if ( isset( $this->comment_transitions[$comment->comment_ID] ) ) {
- // status changed more than once - keep tha most recent $new_status
- $this->comment_transitions[$comment->comment_ID][0] = $new_status;
- } else {
- $this->comment_transitions[$comment->comment_ID] = array( $new_status, $old_status );
- }
-
- $post_sync = $this->get_post_sync_operation( $post->post_status, '_jetpack_test_sync', $post, $this->sync_conditions['comments'] );
-
- if ( !$post_sync ) {
- // No module wants to sync this comment because its post doesn't match any sync conditions
- return false;
- }
-
- if ( 'delete' == $post_sync['operation'] ) {
- // Had we been looking at post sync operations (instead of comment sync operations),
- // this comment's post would have been deleted. Don't sync the comment.
- return false;
- }
-
- $delete_on_behalf_of = array();
- $submit_on_behalf_of = array();
- $delete_stati = array( 'delete' );
-
- foreach ( $this->sync_conditions['comments'] as $module => $conditions ) {
- if ( !in_array( $comment->comment_type, $conditions['comment_types'] ) ) {
- continue;
- }
-
- $deleted_comment = in_array( $new_status, $delete_stati );
-
- if ( $deleted_comment ) {
- $delete_on_behalf_of[] = $module;
- }
-
- $old_status_in_stati = in_array( $old_status, $conditions['comment_stati'] );
- $new_status_in_stati = in_array( $new_status, $conditions['comment_stati'] );
-
- if ( $old_status_in_stati && !$new_status_in_stati ) {
- // Jetpack no longer needs the comment
- if ( !$deleted_comment ) {
- $delete_on_behalf_of[] = $module;
- } // else, we've already flagged it above
- continue;
- }
-
- if ( !$new_status_in_stati ) {
- continue;
- }
-
- // At this point, we know we want to sync the comment, not delete it
- $submit_on_behalf_of[] = $module;
- }
-
- if ( ! empty( $submit_on_behalf_of ) ) {
- $this->register_post( $comment->comment_post_ID, array( 'on_behalf_of' => $submit_on_behalf_of ) );
- return $this->register_comment( $comment->comment_ID, array( 'on_behalf_of' => $submit_on_behalf_of ) );
- }
-
- if ( !empty( $delete_on_behalf_of ) ) {
- return $this->register( 'delete_comment', $comment->comment_ID, array( 'on_behalf_of' => $delete_on_behalf_of ) );
- }
-
- return false;
- }
-
- /**
- * Get a comment and associated data in the standard JP format.
- * Cannot be called statically
- *
- * @param int $id Comment ID
- * @return Array containing full comment details
- */
- function get_comment( $id ) {
- $comment_obj = get_comment( $id );
- if ( !$comment_obj )
- return false;
- $comment = get_object_vars( $comment_obj );
-
- $meta = get_comment_meta( $id, false );
- $comment['meta'] = array();
- foreach ( $meta as $key => $value ) {
- $comment['meta'][$key] = array_map( 'maybe_unserialize', $value );
- }
-
- return $comment;
- }
-
-/* Options Sync */
-
- /* Ah... so much simpler than Posts and Comments :) */
- function options( $file, $option /*, $option, ... */ ) {
- $options = func_get_args();
- $file = array_shift( $options );
-
- $module_slug = Jetpack::get_module_slug( $file );
-
- if ( !isset( $this->sync_options[$module_slug] ) ) {
- $this->sync_options[$module_slug] = array();
- }
-
- foreach ( $options as $option ) {
- $this->sync_options[$module_slug][] = $option;
- add_action( "delete_option_{$option}", array( $this, 'deleted_option_action' ) );
- add_action( "update_option_{$option}", array( $this, 'updated_option_action' ) );
- add_action( "add_option_{$option}", array( $this, 'added_option_action' ) );
- }
-
- $this->sync_options[$module_slug] = array_unique( $this->sync_options[$module_slug] );
- }
-
- function deleted_option_action( $option ) {
- $this->register( 'delete_option', $option );
- }
-
- function updated_option_action( $old_value ) {
- // The value of $option isn't passed to the filter
- // Calculate it
- $option = current_filter();
- $prefix = 'update_option_';
- if ( 0 !== strpos( $option, $prefix ) ) {
- return;
- }
- $option = substr( $option, strlen( $prefix ) );
-
- $this->added_option_action( $option );
- }
-
- function added_option_action( $option ) {
- $this->register( 'option', $option );
- }
-
- function sync_all_module_options( $module_slug ) {
- if ( empty( $this->sync_options[$module_slug] ) ) {
- return;
- }
-
- foreach ( $this->sync_options[$module_slug] as $option ) {
- $this->added_option_action( $option );
- }
- }
-
- function sync_all_registered_options( $options = array() ) {
- if ( 'jetpack_sync_all_registered_options' == current_filter() ) {
- $all_registered_options = array_unique( call_user_func_array( 'array_merge', $this->sync_options ) );
- foreach ( $all_registered_options as $option ) {
- $this->added_option_action( $option );
- }
- } else {
- wp_schedule_single_event( time(), 'jetpack_sync_all_registered_options', array( $this->sync_options ) );
- }
- }
-}
-
-require_once dirname( __FILE__ ) . '/class.jetpack-user-agent.php';
-require_once dirname( __FILE__ ) . '/class.jetpack-post-images.php';
-require_once dirname( __FILE__ ) . '/class.photon.php';
-require dirname( __FILE__ ) . '/functions.photon.php';
-require dirname( __FILE__ ) . '/functions.compat.php';
-require dirname( __FILE__ ) . '/functions.gallery.php';
-
-class Jetpack_Error extends WP_Error {}
+// Constants for expressing human-readable intervals
+// in their respective number of seconds.
+// Introduced in WordPress 3.5, specified here for backward compatability.
+defined( 'MINUTE_IN_SECONDS' ) or define( 'MINUTE_IN_SECONDS', 60 );
+defined( 'HOUR_IN_SECONDS' ) or define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS );
+defined( 'DAY_IN_SECONDS' ) or define( 'DAY_IN_SECONDS', 24 * HOUR_IN_SECONDS );
+defined( 'WEEK_IN_SECONDS' ) or define( 'WEEK_IN_SECONDS', 7 * DAY_IN_SECONDS );
+defined( 'YEAR_IN_SECONDS' ) or define( 'YEAR_IN_SECONDS', 365 * DAY_IN_SECONDS );
+
+// @todo: Abstract out the admin functions, and only include them if is_admin()
+// @todo: Only include things like class.jetpack-sync.php if we're connected.
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-client.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-data.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-client-server.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-sync.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-options.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-user-agent.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-post-images.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-error.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-debugger.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-heartbeat.php' );
+require_once( JETPACK__PLUGIN_DIR . 'class.photon.php' );
+require_once( JETPACK__PLUGIN_DIR . 'functions.photon.php' );
+require_once( JETPACK__PLUGIN_DIR . 'functions.compat.php' );
+require_once( JETPACK__PLUGIN_DIR . 'functions.gallery.php' );
register_activation_hook( __FILE__, array( 'Jetpack', 'plugin_activation' ) );
register_deactivation_hook( __FILE__, array( 'Jetpack', 'plugin_deactivation' ) );
add_action( 'init', array( 'Jetpack', 'init' ) );
+add_action( 'init', array( 'Jetpack_Heartbeat', 'init' ), 100 );
add_action( 'plugins_loaded', array( 'Jetpack', 'load_modules' ), 100 );
add_filter( 'jetpack_static_url', array( 'Jetpack', 'staticize_subdomain' ) );
+/*
+if ( is_admin() && ! Jetpack::check_identity_crisis() ) {
+ Jetpack_Sync::sync_options( __FILE__, 'db_version', 'jetpack_active_modules', 'active_plugins' );
+}
+*/
+
Jetpack_Sync::sync_options( __FILE__, 'widget_twitter' );
diff --git a/plugins/jetpack/languages/jetpack-ar.mo b/plugins/jetpack/languages/jetpack-ar.mo
index 254be8e6..e057c917 100644
--- a/plugins/jetpack/languages/jetpack-ar.mo
+++ b/plugins/jetpack/languages/jetpack-ar.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-az.mo b/plugins/jetpack/languages/jetpack-az.mo
index 033f8593..1a17b7b7 100644
--- a/plugins/jetpack/languages/jetpack-az.mo
+++ b/plugins/jetpack/languages/jetpack-az.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-bs_BA.mo b/plugins/jetpack/languages/jetpack-bs_BA.mo
index 67cd4468..40cc45bd 100644
--- a/plugins/jetpack/languages/jetpack-bs_BA.mo
+++ b/plugins/jetpack/languages/jetpack-bs_BA.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-ca.mo b/plugins/jetpack/languages/jetpack-ca.mo
index 2daa9e1c..68167b29 100644
--- a/plugins/jetpack/languages/jetpack-ca.mo
+++ b/plugins/jetpack/languages/jetpack-ca.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-cs_CZ.mo b/plugins/jetpack/languages/jetpack-cs_CZ.mo
index 5e088773..220421d8 100644
--- a/plugins/jetpack/languages/jetpack-cs_CZ.mo
+++ b/plugins/jetpack/languages/jetpack-cs_CZ.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-da_DK.mo b/plugins/jetpack/languages/jetpack-da_DK.mo
index 773e5b51..c5af6d83 100644
--- a/plugins/jetpack/languages/jetpack-da_DK.mo
+++ b/plugins/jetpack/languages/jetpack-da_DK.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-de_DE.mo b/plugins/jetpack/languages/jetpack-de_DE.mo
index a93c1c7c..c9b11ee7 100644
--- a/plugins/jetpack/languages/jetpack-de_DE.mo
+++ b/plugins/jetpack/languages/jetpack-de_DE.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-el.mo b/plugins/jetpack/languages/jetpack-el.mo
index 8538e68c..6487268b 100644
--- a/plugins/jetpack/languages/jetpack-el.mo
+++ b/plugins/jetpack/languages/jetpack-el.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-es_ES.mo b/plugins/jetpack/languages/jetpack-es_ES.mo
index 3cc9243e..4f8be590 100644
--- a/plugins/jetpack/languages/jetpack-es_ES.mo
+++ b/plugins/jetpack/languages/jetpack-es_ES.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-fa_IR.mo b/plugins/jetpack/languages/jetpack-fa_IR.mo
index f34c74e6..096ac421 100644
--- a/plugins/jetpack/languages/jetpack-fa_IR.mo
+++ b/plugins/jetpack/languages/jetpack-fa_IR.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-fi.mo b/plugins/jetpack/languages/jetpack-fi.mo
index 591c0472..913b15a1 100644
--- a/plugins/jetpack/languages/jetpack-fi.mo
+++ b/plugins/jetpack/languages/jetpack-fi.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-fr_FR.mo b/plugins/jetpack/languages/jetpack-fr_FR.mo
index 165c2b9e..5fa71ada 100644
--- a/plugins/jetpack/languages/jetpack-fr_FR.mo
+++ b/plugins/jetpack/languages/jetpack-fr_FR.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-gl_ES.mo b/plugins/jetpack/languages/jetpack-gl_ES.mo
index e5f4c09a..2e88f28f 100644
--- a/plugins/jetpack/languages/jetpack-gl_ES.mo
+++ b/plugins/jetpack/languages/jetpack-gl_ES.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-he_IL.mo b/plugins/jetpack/languages/jetpack-he_IL.mo
index 90d820c7..cf18acd8 100644
--- a/plugins/jetpack/languages/jetpack-he_IL.mo
+++ b/plugins/jetpack/languages/jetpack-he_IL.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-hr.mo b/plugins/jetpack/languages/jetpack-hr.mo
index 8765f205..d1608ba4 100644
--- a/plugins/jetpack/languages/jetpack-hr.mo
+++ b/plugins/jetpack/languages/jetpack-hr.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-hu_HU.mo b/plugins/jetpack/languages/jetpack-hu_HU.mo
index 11715656..27fbc982 100644
--- a/plugins/jetpack/languages/jetpack-hu_HU.mo
+++ b/plugins/jetpack/languages/jetpack-hu_HU.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-id_ID.mo b/plugins/jetpack/languages/jetpack-id_ID.mo
index 8d3427dd..c0cddc06 100644
--- a/plugins/jetpack/languages/jetpack-id_ID.mo
+++ b/plugins/jetpack/languages/jetpack-id_ID.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-it_IT.mo b/plugins/jetpack/languages/jetpack-it_IT.mo
index 7165de10..fc6d8f41 100644
--- a/plugins/jetpack/languages/jetpack-it_IT.mo
+++ b/plugins/jetpack/languages/jetpack-it_IT.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-ja.mo b/plugins/jetpack/languages/jetpack-ja.mo
index f715cc91..698be13f 100644
--- a/plugins/jetpack/languages/jetpack-ja.mo
+++ b/plugins/jetpack/languages/jetpack-ja.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-ko_KR.mo b/plugins/jetpack/languages/jetpack-ko_KR.mo
index 3a7a5295..46a7b085 100644
--- a/plugins/jetpack/languages/jetpack-ko_KR.mo
+++ b/plugins/jetpack/languages/jetpack-ko_KR.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-lt_LT.mo b/plugins/jetpack/languages/jetpack-lt_LT.mo
index 55f190a5..3917f2f6 100644
--- a/plugins/jetpack/languages/jetpack-lt_LT.mo
+++ b/plugins/jetpack/languages/jetpack-lt_LT.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-mk_MK.mo b/plugins/jetpack/languages/jetpack-mk_MK.mo
index 804e8a3b..4fc204dc 100644
--- a/plugins/jetpack/languages/jetpack-mk_MK.mo
+++ b/plugins/jetpack/languages/jetpack-mk_MK.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-my_MM.mo b/plugins/jetpack/languages/jetpack-my_MM.mo
index 1d1604b7..02d9ab35 100644
--- a/plugins/jetpack/languages/jetpack-my_MM.mo
+++ b/plugins/jetpack/languages/jetpack-my_MM.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-nb_NO.mo b/plugins/jetpack/languages/jetpack-nb_NO.mo
index 5600cf1d..ba9a07ea 100644
--- a/plugins/jetpack/languages/jetpack-nb_NO.mo
+++ b/plugins/jetpack/languages/jetpack-nb_NO.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-nl_NL.mo b/plugins/jetpack/languages/jetpack-nl_NL.mo
index a125514d..3e5b3235 100644
--- a/plugins/jetpack/languages/jetpack-nl_NL.mo
+++ b/plugins/jetpack/languages/jetpack-nl_NL.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-nn_NO.mo b/plugins/jetpack/languages/jetpack-nn_NO.mo
index 1157c955..e97633a0 100644
--- a/plugins/jetpack/languages/jetpack-nn_NO.mo
+++ b/plugins/jetpack/languages/jetpack-nn_NO.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-pl_PL.mo b/plugins/jetpack/languages/jetpack-pl_PL.mo
index 3a5df93c..3e686606 100644
--- a/plugins/jetpack/languages/jetpack-pl_PL.mo
+++ b/plugins/jetpack/languages/jetpack-pl_PL.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-pt_BR.mo b/plugins/jetpack/languages/jetpack-pt_BR.mo
index da51355f..a4aa2278 100644
--- a/plugins/jetpack/languages/jetpack-pt_BR.mo
+++ b/plugins/jetpack/languages/jetpack-pt_BR.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-pt_PT.mo b/plugins/jetpack/languages/jetpack-pt_PT.mo
index 62d6331b..8afc9be6 100644
--- a/plugins/jetpack/languages/jetpack-pt_PT.mo
+++ b/plugins/jetpack/languages/jetpack-pt_PT.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-ro_RO.mo b/plugins/jetpack/languages/jetpack-ro_RO.mo
index 6a76116e..6b6b6e34 100644
--- a/plugins/jetpack/languages/jetpack-ro_RO.mo
+++ b/plugins/jetpack/languages/jetpack-ro_RO.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-ru_RU.mo b/plugins/jetpack/languages/jetpack-ru_RU.mo
index 392de6d0..12ab4527 100644
--- a/plugins/jetpack/languages/jetpack-ru_RU.mo
+++ b/plugins/jetpack/languages/jetpack-ru_RU.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-sa_IN.mo b/plugins/jetpack/languages/jetpack-sa_IN.mo
index f7bfee62..6e87f221 100644
--- a/plugins/jetpack/languages/jetpack-sa_IN.mo
+++ b/plugins/jetpack/languages/jetpack-sa_IN.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-sk_SK.mo b/plugins/jetpack/languages/jetpack-sk_SK.mo
index 0f6a8ea8..8cb30748 100644
--- a/plugins/jetpack/languages/jetpack-sk_SK.mo
+++ b/plugins/jetpack/languages/jetpack-sk_SK.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-sq.mo b/plugins/jetpack/languages/jetpack-sq.mo
index 795f5abb..87856508 100644
--- a/plugins/jetpack/languages/jetpack-sq.mo
+++ b/plugins/jetpack/languages/jetpack-sq.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-sr_RS.mo b/plugins/jetpack/languages/jetpack-sr_RS.mo
index 62d2959a..c6d753d8 100644
--- a/plugins/jetpack/languages/jetpack-sr_RS.mo
+++ b/plugins/jetpack/languages/jetpack-sr_RS.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-sv_SE.mo b/plugins/jetpack/languages/jetpack-sv_SE.mo
index 382cbc3e..60b01b1c 100644
--- a/plugins/jetpack/languages/jetpack-sv_SE.mo
+++ b/plugins/jetpack/languages/jetpack-sv_SE.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-th.mo b/plugins/jetpack/languages/jetpack-th.mo
index 13499189..f747b319 100644
--- a/plugins/jetpack/languages/jetpack-th.mo
+++ b/plugins/jetpack/languages/jetpack-th.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-tr_TR.mo b/plugins/jetpack/languages/jetpack-tr_TR.mo
index 24eeccec..09c04155 100644
--- a/plugins/jetpack/languages/jetpack-tr_TR.mo
+++ b/plugins/jetpack/languages/jetpack-tr_TR.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-zh_CN.mo b/plugins/jetpack/languages/jetpack-zh_CN.mo
index 17900fb1..d4fa8db8 100644
--- a/plugins/jetpack/languages/jetpack-zh_CN.mo
+++ b/plugins/jetpack/languages/jetpack-zh_CN.mo
Binary files differ
diff --git a/plugins/jetpack/languages/jetpack-zh_TW.mo b/plugins/jetpack/languages/jetpack-zh_TW.mo
index 38662136..fda55d22 100644
--- a/plugins/jetpack/languages/jetpack-zh_TW.mo
+++ b/plugins/jetpack/languages/jetpack-zh_TW.mo
Binary files differ
diff --git a/plugins/jetpack/locales.php b/plugins/jetpack/locales.php
index e910fbfc..5c306d49 100644
--- a/plugins/jetpack/locales.php
+++ b/plugins/jetpack/locales.php
@@ -1773,28 +1773,28 @@ class GP_Locales {
}
}
- function &instance() {
+ static function instance() {
if ( !isset( $GLOBALS['gp_locales'] ) )
$GLOBALS['gp_locales'] = new GP_Locales;
return $GLOBALS['gp_locales'];
}
- function locales() {
+ static function locales() {
$instance = GP_Locales::instance();
return $instance->locales;
}
- function exists( $slug ) {
+ static function exists( $slug ) {
$instance = GP_Locales::instance();
return isset( $instance->locales[$slug] );
}
- function by_slug( $slug ) {
+ static function by_slug( $slug ) {
$instance = GP_Locales::instance();
return isset( $instance->locales[$slug] )? $instance->locales[$slug] : null;
}
- function by_field( $field_name, $field_value ) {
+ static function by_field( $field_name, $field_value ) {
$instance = GP_Locales::instance();
$result = false;
foreach( $instance->locales() as $locale ) {
diff --git a/plugins/jetpack/modules/after-the-deadline.php b/plugins/jetpack/modules/after-the-deadline.php
index 606f6488..cf98ec0c 100644
--- a/plugins/jetpack/modules/after-the-deadline.php
+++ b/plugins/jetpack/modules/after-the-deadline.php
@@ -4,21 +4,22 @@
* Module Description: Improve your spelling, style, and grammar with the <a href="http://www.afterthedeadline.com/">After&nbsp;the&nbsp;Deadline</a> Proofreading service.
* Sort Order: 6
* First Introduced: 1.1
+ * Requires Connection: Yes
*/
-
+
add_action( 'jetpack_modules_loaded', 'AtD_load' );
function AtD_load() {
- Jetpack::enable_module_configurable( __FILE__ );
- Jetpack::module_configuration_load( __FILE__, 'AtD_configuration_load' );
+ Jetpack::enable_module_configurable( __FILE__ );
+ Jetpack::module_configuration_load( __FILE__, 'AtD_configuration_load' );
}
function AtD_configuration_load() {
wp_safe_redirect( get_edit_profile_url( get_current_user_id() ) . '#atd' );
- exit;
+ exit;
}
-/*
+/*
* Load necessary include files
*/
include( 'after-the-deadline/config-options.php' );
@@ -56,7 +57,7 @@ function AtD_addbuttons() {
/* Don't bother doing this stuff if the current user lacks permissions */
if ( ! AtD_is_allowed() )
return;
-
+
/* Add only in Rich Editor mode */
if ( get_user_option( 'rich_editing' ) == 'true' ) {
add_filter( 'mce_external_plugins', 'add_AtD_tinymce_plugin' );
@@ -85,16 +86,16 @@ function register_AtD_button( $buttons ) {
array_push( $buttons, '|', 'AtD' );
return $buttons;
}
-
+
/*
- * Load the TinyMCE plugin : editor_plugin.js (wp2.5)
+ * Load the TinyMCE plugin : editor_plugin.js (wp2.5)
*/
function add_AtD_tinymce_plugin( $plugin_array ) {
$plugin_array['AtD'] = plugins_url( 'after-the-deadline/tinymce/editor_plugin.js?v=' . ATD_VERSION, __FILE__ );
return $plugin_array;
}
-/*
+/*
* Update the TinyMCE init block with AtD specific settings
*/
function AtD_change_mce_settings( $init_array ) {
@@ -116,15 +117,15 @@ function AtD_change_mce_settings( $init_array ) {
return $init_array;
}
-/*
+/*
* Sanitizes AtD AJAX data to acceptable chars, caller needs to make sure ' is escaped
*/
function AtD_sanitize( $untrusted ) {
return preg_replace( '/[^a-zA-Z0-9\-\',_ ]/i', "", $untrusted );
}
-/*
- * AtD HTML Editor Stuff
+/*
+ * AtD HTML Editor Stuff
*/
function AtD_settings() {
$user = wp_get_current_user();
@@ -156,20 +157,20 @@ function AtD_load_javascripts() {
wp_enqueue_script( 'AtD_jquery', plugins_url( '/after-the-deadline/jquery.atd.js', __FILE__ ), array('jquery'), ATD_VERSION );
wp_enqueue_script( 'AtD_settings', admin_url() . 'admin-ajax.php?action=atd_settings', array('AtD_jquery'), ATD_VERSION );
wp_enqueue_script( 'AtD_autoproofread', plugins_url( '/after-the-deadline/atd-autoproofread.js', __FILE__ ), array('AtD_jquery'), ATD_VERSION );
- }
+ }
}
/* Spits out user options for auto-proofreading on publish/update */
function AtD_load_submit_check_javascripts() {
global $pagenow;
-
+
$user = wp_get_current_user();
if ( ! $user || $user->ID == 0 )
return;
-
+
if ( AtD_should_load_on_page() ) {
$atd_check_when = AtD_get_setting( $user->ID, 'AtD_check_when' );
-
+
if ( !empty( $atd_check_when ) ) {
$check_when = array();
/* Set up the options in json */
@@ -238,7 +239,7 @@ add_action( 'init', 'AtD_addbuttons' );
/* setup hooks for our PHP functions we want to make available via an AJAX call */
add_action( 'wp_ajax_proxy_atd', 'AtD_redirect_call' );
-add_action( 'wp_ajax_atd_ignore', 'AtD_ignore_call' );
+add_action( 'wp_ajax_atd_ignore', 'AtD_ignore_call' );
add_action( 'wp_ajax_atd_settings', 'AtD_settings' );
/* load and install the localization stuff */
diff --git a/plugins/jetpack/modules/after-the-deadline/atd-autoproofread.js b/plugins/jetpack/modules/after-the-deadline/atd-autoproofread.js
index b76a757c..53ef766d 100644
--- a/plugins/jetpack/modules/after-the-deadline/atd-autoproofread.js
+++ b/plugins/jetpack/modules/after-the-deadline/atd-autoproofread.js
@@ -37,13 +37,13 @@ function AtD_submit_check_callback(count) {
} else {
var original_post_status = jQuery('#original_post_status').val()
- /* Okay, the user has tried to publish/update already but there are still errors. Ask them what to do */
+ /* Okay, the user has tried to publish/update already but there are still errors. Ask them what to do */
var message;
if ( original_post_status == 'publish' )
message = AtD.getLang('dialog_confirm_post_publish', 'The proofreader has suggestions for this post. Are you sure you want to publish it?\n\nPress OK to publish your post, or Cancel to view the suggestions and edit your post.');
else
message = AtD.getLang('dialog_confirm_post_update', 'The proofreader has suggestions for this post. Are you sure you want to update it?\n\nPress OK to update your post, or Cancel to view the suggestions and edit your post.');
-
+
if ( confirm( message ) ) {
AtD_update_post();
} else {
@@ -66,7 +66,7 @@ function AtD_kill_autoproofread() {
function AtD_update_post() {
if ( typeof(tinyMCE) == 'undefined' || !tinyMCE.activeEditor || tinyMCE.activeEditor.isHidden() )
- AtD_restore_if_proofreading();
+ AtD_restore_if_proofreading();
jQuery('#publish').unbind('click.AtD_submit_check').click();
}
diff --git a/plugins/jetpack/modules/after-the-deadline/atd-nonvis-editor-plugin.js b/plugins/jetpack/modules/after-the-deadline/atd-nonvis-editor-plugin.js
index 5d84497d..88f2d9c8 100644
--- a/plugins/jetpack/modules/after-the-deadline/atd-nonvis-editor-plugin.js
+++ b/plugins/jetpack/modules/after-the-deadline/atd-nonvis-editor-plugin.js
@@ -3,7 +3,7 @@ var AtD_qtbutton;
function AtD_restore_text_area()
{
/* clear the error HTML out of the preview div */
- AtD.remove('content');
+ AtD.remove('content');
/* swap the preview div for the textarea, notice how I have to restore the appropriate class/id/style attributes */
var content = jQuery('#content').html();
@@ -13,7 +13,7 @@ function AtD_restore_text_area()
jQuery('#content').replaceWith( AtD.content_canvas );
jQuery('#content').val( content.replace(/\&lt\;/g, '<').replace(/\&gt\;/g, '>').replace(/\&amp;/g, '&') );
- jQuery('#content').height(AtD.height);
+ jQuery('#content').height(AtD.height);
if ( AtD_qtbutton ) {
/* change the link text back to its original label */
@@ -42,7 +42,7 @@ if ( typeof(QTags) != 'undefined' && QTags.addButton ) {
}
function AtD_restore_if_proofreading() {
- if ( AtD_qtbutton && jQuery(AtD_qtbutton).val() == AtD.getLang('button_edit_text', 'edit text') )
+ if ( AtD_qtbutton && jQuery(AtD_qtbutton).val() == AtD.getLang('button_edit_text', 'edit text') )
AtD_restore_text_area();
}
@@ -84,8 +84,8 @@ function AtD_check(button) {
/* If the text of the link says edit comment, then restore the textarea so the user can edit the text */
- if ( jQuery(AtD_qtbutton).val() == AtD.getLang('button_edit_text', 'edit text') ) {
- AtD_restore_text_area();
+ if ( jQuery(AtD_qtbutton).val() == AtD.getLang('button_edit_text', 'edit text') ) {
+ AtD_restore_text_area();
} else {
/* initialize some of the stuff related to this plugin */
if ( !AtD.height ) {
@@ -124,7 +124,7 @@ function AtD_check(button) {
} else {
jQuery('#content').replaceWith('<div class="input" id="content">' + text + '</div>');
jQuery('#content').css( { 'overflow' : 'auto', 'background-color' : 'white', 'color' : 'black', 'white-space' : 'pre-wrap' } );
- jQuery('#content').height(AtD.height);
+ jQuery('#content').height(AtD.height);
}
/* kill autosave... :) */
@@ -144,16 +144,16 @@ function AtD_check(button) {
ready: function(errorCount) {
jQuery(AtD_qtbutton).attr('disabled', false);
- if ( typeof callback === 'function' )
+ if ( typeof callback === 'function' )
callback( errorCount );
},
error: function(reason) {
jQuery(AtD_qtbutton).attr('disabled', false);
- if ( typeof callback === 'function' )
+ if ( typeof callback === 'function' )
callback( -1 );
- else
+ else
alert( AtD.getLang('message_server_error', 'There was a problem communicating with the Proofreading service. Try again in one minute.') );
AtD_restore_if_proofreading();
@@ -164,7 +164,7 @@ function AtD_check(button) {
if ( text != null )
element.replaceWith( text );
- },
+ },
explain: function(url) {
var left = (screen.width / 2) - (480 / 2);
diff --git a/plugins/jetpack/modules/after-the-deadline/atd.core.js b/plugins/jetpack/modules/after-the-deadline/atd.core.js
index 0e3d1c4c..5d6efc91 100644
--- a/plugins/jetpack/modules/after-the-deadline/atd.core.js
+++ b/plugins/jetpack/modules/after-the-deadline/atd.core.js
@@ -74,18 +74,18 @@ AtDCore.prototype.showTypes = function(string) {
});
this.map(this.ignore_types, function(string) {
- if (types[string] != undefined)
+ if (types[string] != undefined)
ignore_types.push(string);
});
this.ignore_types = ignore_types;
};
-/*
+/*
* Error Parsing Code
*/
-AtDCore.prototype.makeError = function(error_s, tokens, type, seps, pre) {
+AtDCore.prototype.makeError = function(error_s, tokens, type, seps, pre) {
var struct = new Object();
struct.type = type;
struct.string = error_s;
@@ -110,20 +110,20 @@ AtDCore.prototype.makeError = function(error_s, tokens, type, seps, pre) {
};
AtDCore.prototype.addToErrorStructure = function(errors, list, type, seps) {
- var parent = this;
+ var parent = this;
this.map(list, function(error) {
var tokens = error["word"].split(/\s+/);
var pre = error["pre"];
var first = tokens[0];
- if (errors['__' + first] == undefined) {
+ if (errors['__' + first] == undefined) {
errors['__' + first] = new Object();
errors['__' + first].pretoks = {};
errors['__' + first].defaults = new Array();
}
- if (pre == "") {
+ if (pre == "") {
errors['__' + first].defaults.push(parent.makeError(error["word"], tokens, type, seps, pre));
} else {
if (errors['__' + first].pretoks['__' + pre] == undefined)
@@ -138,7 +138,7 @@ AtDCore.prototype.buildErrorStructure = function(spellingList, enrichmentList, g
var seps = this._getSeparators();
var errors = {};
- this.addToErrorStructure(errors, spellingList, "hiddenSpellError", seps);
+ this.addToErrorStructure(errors, spellingList, "hiddenSpellError", seps);
this.addToErrorStructure(errors, grammarList, "hiddenGrammarError", seps);
this.addToErrorStructure(errors, enrichmentList, "hiddenSuggestion", seps);
return errors;
@@ -153,7 +153,7 @@ AtDCore.prototype._getSeparators = function() {
re += '\\' + str.charAt(i);
return "(?:(?:[\xa0" + re + "])|(?:\\-\\-))+";
-};
+};
AtDCore.prototype.processXML = function(responseXML) {
@@ -183,8 +183,8 @@ AtDCore.prototype.processXML = function(responseXML) {
var errorContext;
- if (errors[i].getElementsByTagName('precontext').item(0).firstChild != null)
- errorContext = errors[i].getElementsByTagName('precontext').item(0).firstChild.data;
+ if (errors[i].getElementsByTagName('precontext').item(0).firstChild != null)
+ errorContext = errors[i].getElementsByTagName('precontext').item(0).firstChild.data;
else
errorContext = "";
@@ -236,11 +236,11 @@ AtDCore.prototype.processXML = function(responseXML) {
if (errorDescription == "Repeated Word")
suggestion["description"] = this.getLang('menu_title_repeated_word', 'Repeated Word');
-
+
if (errorDescription == "Did you mean...")
suggestion["description"] = this.getLang('menu_title_confused_word', 'Did you mean...');
} // end if ignore[errorString] == undefined
- } // end if
+ } // end if
} // end for loop
var errorStruct;
@@ -265,10 +265,10 @@ AtDCore.prototype.findSuggestion = function(element) {
var errorDescription = undefined;
var len = this.suggestions.length;
-
+
for (var i = 0; i < len; i++) {
var key = this.suggestions[i]["string"];
-
+
if ((context == "" || context == this.suggestions[i]["context"]) && this.suggestions[i]["matcher"].test(text)) {
errorDescription = this.suggestions[i];
break;
@@ -299,7 +299,7 @@ TokenIterator.prototype.next = function() {
if (current[0] == "'")
current = current.substring(1, current.length);
- if (current[current.length - 1] == "'")
+ if (current[current.length - 1] == "'")
current = current.substring(0, current.length - 1);
}
@@ -311,7 +311,7 @@ TokenIterator.prototype.hasNext = function() {
};
TokenIterator.prototype.hasNextN = function(n) {
- return (this.index + n) < this.tokens.length;
+ return (this.index + n) < this.tokens.length;
};
TokenIterator.prototype.skip = function(m, n) {
@@ -334,10 +334,10 @@ TokenIterator.prototype.peek = function(n) {
return peepers;
};
-/*
+/*
* code to manage highlighting of errors
*/
-AtDCore.prototype.markMyWords = function(container_nodes, errors) {
+AtDCore.prototype.markMyWords = function(container_nodes, errors) {
var seps = new RegExp(this._getSeparators());
var nl = new Array();
var ecount = 0; /* track number of highlighted errors */
@@ -345,16 +345,16 @@ AtDCore.prototype.markMyWords = function(container_nodes, errors) {
/* Collect all text nodes */
/* Our goal--ignore nodes that are already wrapped */
-
+
this._walk(container_nodes, function(n) {
if (n.nodeType == 3 && !parent.isMarkedNode(n))
nl.push(n);
});
-
- /* walk through the relevant nodes */
-
+
+ /* walk through the relevant nodes */
+
var iterator;
-
+
this.map(nl, function(n) {
var v;
@@ -431,7 +431,7 @@ AtDCore.prototype.markMyWords = function(container_nodes, errors) {
return parent.create('<span class="mceItemHidden">&nbsp;</span>' + node.nodeValue.substr(1, node.nodeValue.length - 1).replace(regexp, result), false);
else
return parent.create(node.nodeValue.replace(regexp, result), false);
- }
+ }
else {
var contents = parent.contents(node);
@@ -462,8 +462,8 @@ AtDCore.prototype.markMyWords = function(container_nodes, errors) {
parent.replaceWith(n, newNode);
}
- }
- });
+ }
+ });
return ecount;
};
@@ -474,9 +474,9 @@ AtDCore.prototype._walk = function(elements, f) {
f.call(f, elements[i]);
this._walk(this.contents(elements[i]), f);
}
-};
+};
-AtDCore.prototype.removeWords = function(node, w) {
+AtDCore.prototype.removeWords = function(node, w) {
var count = 0;
var parent = this;
@@ -518,7 +518,7 @@ AtDCore.prototype.applySuggestion = function(element, suggestion) {
}
};
-/*
+/*
* Check for an error
*/
AtDCore.prototype.hasErrorMessage = function(xmlr) {
diff --git a/plugins/jetpack/modules/after-the-deadline/atd.css b/plugins/jetpack/modules/after-the-deadline/atd.css
index 5014feac..2f59bd21 100644
--- a/plugins/jetpack/modules/after-the-deadline/atd.css
+++ b/plugins/jetpack/modules/after-the-deadline/atd.css
@@ -25,7 +25,7 @@
* Project : http://jquery-spellchecker.googlecode.com
*/
-#suggestmenu
+#suggestmenu
{
min-width: 122px;
background: #ebeaeb;
@@ -39,27 +39,27 @@
font-family: Tahoma, Verdana, Arial, Helvetica;
}
-#suggestmenu strong
+#suggestmenu strong
{
background: #cccccc;
font-weight: bold;
- padding:3px 6px 3px 6px;
- display:block;
+ padding:3px 6px 3px 6px;
+ display:block;
border:1px solid #dddddd;
- border-bottom: 1px solid #aaaaaa;
+ border-bottom: 1px solid #aaaaaa;
color: black;
}
-#suggestmenu em
+#suggestmenu em
{
- text-align:center;
- padding:3px 6px 3px 6px;
- display:block;
+ text-align:center;
+ padding:3px 6px 3px 6px;
+ display:block;
border-top:1px solid #ccc;
border-left:1px solid #ccc;
}
-#suggestmenu a, #suggestmenu a:visited
+#suggestmenu a, #suggestmenu a:visited
{
background: #ebeaeb;
border-left:1px solid #dddddd;
@@ -72,34 +72,34 @@
outline:none
}
-#suggestmenu a.first, #suggestmenu a.first:visited
+#suggestmenu a.first, #suggestmenu a.first:visited
{
border-top:1px solid #dddddd;
}
-.spell_sep_bottom
+.spell_sep_bottom
{
border-bottom: 1px solid #dddddd;
}
-.spell_sep_top
+.spell_sep_top
{
border-top: 1px solid #aaaaaa;
}
-#suggestmenu a:hover
+#suggestmenu a:hover
{
color:#000;
background: #f5f5f5;
}
-#suggestmenu .foot
+#suggestmenu .foot
{
border-top:1px solid #aaaaaa;
background:#fff
}
-#suggestmenu .foot a, #suggestmenu .foot a:visited
+#suggestmenu .foot a, #suggestmenu .foot a:visited
{
outline:none
}
diff --git a/plugins/jetpack/modules/after-the-deadline/config-options.php b/plugins/jetpack/modules/after-the-deadline/config-options.php
index 097b062d..db4a49c7 100644
--- a/plugins/jetpack/modules/after-the-deadline/config-options.php
+++ b/plugins/jetpack/modules/after-the-deadline/config-options.php
@@ -49,8 +49,8 @@ function AtD_display_options_form() {
<td>
<p><?php _e( 'Automatically proofread content when:', 'jetpack' ); ?>
- <p><?php
- AtD_print_option( 'onpublish', __('a post or page is first published', 'jetpack'), $options_check_when );
+ <p><?php
+ AtD_print_option( 'onpublish', __('a post or page is first published', 'jetpack'), $options_check_when );
echo '<br />';
AtD_print_option( 'onupdate', __('a post or page is updated', 'jetpack'), $options_check_when );
?></p>
@@ -59,12 +59,12 @@ function AtD_display_options_form() {
<p><?php _e('Enable proofreading for the following grammar and style rules when writing posts and pages:', 'jetpack'); ?></p>
- <p><?php
+ <p><?php
AtD_print_option( 'Bias Language', __('Bias Language', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Cliches', __('Clich&eacute;s', 'jetpack'), $options_show_types );
echo '<br />';
- AtD_print_option( 'Complex Expression', __('Complex Phrases', 'jetpack'), $options_show_types );
+ AtD_print_option( 'Complex Expression', __('Complex Phrases', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Diacritical Marks', __('Diacritical Marks', 'jetpack'), $options_show_types );
echo '<br />';
@@ -72,15 +72,15 @@ function AtD_display_options_form() {
echo '<br />';
AtD_print_option( 'Hidden Verbs', __('Hidden Verbs', 'jetpack'), $options_show_types );
echo '<br />';
- AtD_print_option( 'Jargon Language', __('Jargon', 'jetpack'), $options_show_types );
+ AtD_print_option( 'Jargon Language', __('Jargon', 'jetpack'), $options_show_types );
echo '<br />';
- AtD_print_option( 'Passive voice', __('Passive Voice', 'jetpack'), $options_show_types );
+ AtD_print_option( 'Passive voice', __('Passive Voice', 'jetpack'), $options_show_types );
echo '<br />';
- AtD_print_option( 'Phrases to Avoid', __('Phrases to Avoid', 'jetpack'), $options_show_types );
+ AtD_print_option( 'Phrases to Avoid', __('Phrases to Avoid', 'jetpack'), $options_show_types );
echo '<br />';
- AtD_print_option( 'Redundant Expression', __('Redundant Phrases', 'jetpack'), $options_show_types );
+ AtD_print_option( 'Redundant Expression', __('Redundant Phrases', 'jetpack'), $options_show_types );
?></p>
- <p><?php printf( __( '<a href="%s">Learn more</a> about these options.', 'jetpack' ), 'http://support.wordpress.com/proofreading/' );
+ <p><?php printf( __( '<a href="%s">Learn more</a> about these options.', 'jetpack' ), 'http://support.wordpress.com/proofreading/' );
?></p>
<p style="font-weight: bold"><?php _e( 'Language', 'jetpack' ); ?></font>
@@ -103,14 +103,14 @@ function AtD_display_options_form() {
*/
function AtD_get_options( $user_id, $name ) {
$options_raw = AtD_get_setting( $user_id, $name, 'single' );
-
+
$options = array();
$options['name'] = $name;
if ( $options_raw )
- foreach ( explode( ',', $options_raw ) as $option )
+ foreach ( explode( ',', $options_raw ) as $option )
$options[ $option ] = 1;
-
+
return $options;
}
@@ -125,6 +125,6 @@ function AtD_update_options( $user_id, $name ) {
} else {
AtD_update_setting( $user_id, AtD_sanitize( $name ), '');
}
-
+
return;
}
diff --git a/plugins/jetpack/modules/after-the-deadline/config-unignore.php b/plugins/jetpack/modules/after-the-deadline/config-unignore.php
index 9d49fa20..84b18ff6 100644
--- a/plugins/jetpack/modules/after-the-deadline/config-unignore.php
+++ b/plugins/jetpack/modules/after-the-deadline/config-unignore.php
@@ -1,5 +1,5 @@
<?php
-/*
+/*
* Called by the TinyMCE plugin when Ignore Always is clicked (setup as an action through admin-ajax.php)
*/
function AtD_ignore_call() {
@@ -24,7 +24,7 @@ function AtD_ignore_call() {
die();
}
-/*
+/*
* Called when a POST occurs, used to save AtD ignored phrases
*/
function AtD_process_unignore_update() {
@@ -100,10 +100,10 @@ function atd_ignore () {
/* update the UI */
atd_show_phrases( ignored );
- jQuery( '#AtD_add_ignore' ).val('');
+ jQuery( '#AtD_add_ignore' ).val('');
/* show that nifteroo messaroo to the useroo */
- jQuery( '#AtD_message' ).show();
+ jQuery( '#AtD_message' ).show();
}
function atd_ignore_init() {
@@ -124,7 +124,7 @@ else
<input type="hidden" name="AtD_ignored_phrases" id="AtD_ignored_phrases" value="<?php echo esc_attr( $ignores ); ?>">
<p style="font-weight: bold"><?php _e( 'Ignored Phrases', 'jetpack' ); ?></font>
-
+
<p><?php _e( 'Identify words and phrases to ignore while proofreading your posts and pages:', 'jetpack' ); ?></p>
<p><input type="text" id="AtD_add_ignore" name="AtD_add_ignore"> <input type="button" value="<?php _e( 'Add', 'jetpack' ); ?>" onclick="javascript:atd_ignore()"></p>
diff --git a/plugins/jetpack/modules/after-the-deadline/install_atd_l10n.js b/plugins/jetpack/modules/after-the-deadline/install_atd_l10n.js
index 7d18bb9a..3215de66 100644
--- a/plugins/jetpack/modules/after-the-deadline/install_atd_l10n.js
+++ b/plugins/jetpack/modules/after-the-deadline/install_atd_l10n.js
@@ -2,7 +2,7 @@
function atd_sprintf(format, values) {
var result = format;
for (var x = 0; x < values.length; x++)
- result = result.replace(new RegExp('%' + (x + 1) + '\\$', 'g'), values[x]);
+ result = result.replace(new RegExp('%' + (x + 1) + '\\$', 'g'), values[x]);
return result;
}
@@ -15,7 +15,7 @@ function install_atd_l10n() {
/* set the AtD l10n instance */
AtD.addI18n(AtD_l10n_r0ar);
}
-
+
/* document.ready() does not execute in IE6 unless it's at the bottom of the page. oi! */
if (navigator.appName == 'Microsoft Internet Explorer')
setTimeout( install_atd_l10n, 2500 );
diff --git a/plugins/jetpack/modules/after-the-deadline/jquery.atd.js b/plugins/jetpack/modules/after-the-deadline/jquery.atd.js
index e5201079..ee2ef6be 100644
--- a/plugins/jetpack/modules/after-the-deadline/jquery.atd.js
+++ b/plugins/jetpack/modules/after-the-deadline/jquery.atd.js
@@ -5,7 +5,7 @@
* Project : http://www.afterthedeadline.com/development.slp
* Contact : raffi@automattic.com
*
- * Derived from:
+ * Derived from:
*
* jquery.spellchecker.js - a simple jQuery Spell Checker
* Copyright (c) 2008 Richard Willis
@@ -14,7 +14,7 @@
* Contact : willis.rh@gmail.com
*/
-var AtD =
+var AtD =
{
rpc : '', /* see the proxy.php that came with the AtD/TinyMCE plugin */
rpc_css : 'http://www.polishmywriting.com/atd-jquery/server/proxycss.php?data=', /* you may use this, but be nice! */
@@ -46,8 +46,8 @@ AtD.showTypes = function(string) {
AtD.checkCrossAJAX = function(container_id, callback_f) {
/* checks if a global var for click stats exists and increments it if it does... */
- if (typeof AtD_proofread_click_count != "undefined")
- AtD_proofread_click_count++;
+ if (typeof AtD_proofread_click_count != "undefined")
+ AtD_proofread_click_count++;
AtD.callback_f = callback_f; /* remember the callback for later */
AtD.remove(container_id);
@@ -74,7 +74,7 @@ AtD.checkCrossAJAX = function(container_id, callback_f) {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(response);
- }
+ }
else {
xml = (new DOMParser()).parseFromString(response, 'text/xml');
}
@@ -85,7 +85,7 @@ AtD.checkCrossAJAX = function(container_id, callback_f) {
AtD.callback_f.error(AtD.core.getErrorMessage(xml));
return;
- }
+ }
/* highlight the errors */
@@ -107,12 +107,12 @@ AtD.checkCrossAJAX = function(container_id, callback_f) {
AtD.check = function(container_id, callback_f) {
/* checks if a global var for click stats exists and increments it if it does... */
if (typeof AtD_proofread_click_count != "undefined")
- AtD_proofread_click_count++;
+ AtD_proofread_click_count++;
AtD.callback_f = callback_f; /* remember the callback for later */
- AtD.remove(container_id);
-
+ AtD.remove(container_id);
+
var container = jQuery('#' + container_id);
var html = container.html();
@@ -124,14 +124,14 @@ AtD.check = function(container_id, callback_f) {
type : "POST",
url : AtD.rpc + '/checkDocument',
data : 'key=' + AtD.api_key + '&data=' + text,
- format : 'raw',
+ format : 'raw',
dataType : (jQuery.browser.msie) ? "text" : "xml",
error : function(XHR, status, error) {
if (AtD.callback_f != undefined && AtD.callback_f.error != undefined)
AtD.callback_f.error(status + ": " + error);
},
-
+
success : function(data) {
/* apparently IE likes to return XML as plain text-- work around from:
http://docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests */
@@ -141,7 +141,7 @@ AtD.check = function(container_id, callback_f) {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
- }
+ }
else {
xml = data;
}
@@ -169,7 +169,7 @@ AtD.check = function(container_id, callback_f) {
}
});
};
-
+
AtD.remove = function(container_id) {
AtD._removeWords(container_id, null);
};
@@ -182,7 +182,7 @@ AtD.clickListener = function(event) {
AtD.processXML = function(container_id, responseXML) {
var results = AtD.core.processXML(responseXML);
-
+
if (results.count > 0)
results.count = AtD.core.markMyWords(jQuery('#' + container_id).contents(), results.errors);
@@ -214,7 +214,7 @@ AtD.editSelection = function() {
};
AtD.ignoreSuggestion = function() {
- AtD.core.removeParent(AtD.errorElement);
+ AtD.core.removeParent(AtD.errorElement);
AtD.counter --;
if (AtD.counter == 0 && AtD.callback_f != undefined && AtD.callback_f.success != undefined)
@@ -253,7 +253,7 @@ AtD.suggest = function(element) {
suggest.hide();
}
- /* find the correct suggestions object */
+ /* find the correct suggestions object */
errorDescription = AtD.core.findSuggestion(element);
@@ -297,7 +297,7 @@ AtD.suggest = function(element) {
suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')">' + AtD.getLang('menu_option_ignore_always', 'Ignore always') + '</a>');
else
suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')">' + AtD.getLang('menu_option_ignore_all', 'Ignore all') + '</a>');
-
+
suggest.append('<a href="javascript:AtD.editSelection(\'' + AtD.container + '\')" class="spell_sep_bottom spell_sep_top">' + AtD.getLang('menu_option_edit_selection', 'Edit Selection...') + '</a>');
}
else {
@@ -313,8 +313,8 @@ AtD.suggest = function(element) {
var width = jQuery(element).width();
/* a sanity check for Internet Explorer--my favorite browser in every possible way */
- if (width > 100)
- width = 50;
+ if (width > 100)
+ width = 50;
jQuery(suggest).css({ left: (pos.left + width) + 'px', top: pos.top + 'px' });
@@ -327,13 +327,13 @@ AtD.suggest = function(element) {
setTimeout(function() {
jQuery("body").bind("click", function() {
if (!AtD.suggestShow)
- jQuery('#suggestmenu').fadeOut(200);
+ jQuery('#suggestmenu').fadeOut(200);
});
}, 1);
setTimeout(function() {
AtD.suggestShow = false;
- }, 2);
+ }, 2);
};
AtD._removeWords = function(container_id, w) {
@@ -341,7 +341,7 @@ AtD._removeWords = function(container_id, w) {
};
/*
- * Set prototypes used by AtD Core UI
+ * Set prototypes used by AtD Core UI
*/
AtD.initCoreModule = function() {
var core = new AtDCore();
diff --git a/plugins/jetpack/modules/after-the-deadline/proxy.php b/plugins/jetpack/modules/after-the-deadline/proxy.php
index 04bbd285..3d5ef3b6 100644
--- a/plugins/jetpack/modules/after-the-deadline/proxy.php
+++ b/plugins/jetpack/modules/after-the-deadline/proxy.php
@@ -21,21 +21,21 @@ function AtD_http_post( $request, $host, $path, $port = 80 ) {
$AtD_url = "http://{$host}{$path}";
$response = wp_remote_post( $AtD_url, $http_args );
$code = (int) wp_remote_retrieve_response_code( $response );
-
+
if ( is_wp_error( $response ) ) {
do_action( 'atd_http_post_error', 'http-error' );
return array();
} elseif ( 200 != $code ) {
do_action( 'atd_http_post_error', $code );
}
-
+
return array(
- wp_remote_retrieve_headers( $response ),
+ wp_remote_retrieve_headers( $response ),
wp_remote_retrieve_body( $response ),
);
}
-/*
+/*
* This function is called as an action handler to admin-ajax.php
*/
function AtD_redirect_call() {
diff --git a/plugins/jetpack/modules/after-the-deadline/tinymce/editor_plugin.js b/plugins/jetpack/modules/after-the-deadline/tinymce/editor_plugin.js
index fc9f01fe..f9251cd9 100644
--- a/plugins/jetpack/modules/after-the-deadline/tinymce/editor_plugin.js
+++ b/plugins/jetpack/modules/after-the-deadline/tinymce/editor_plugin.js
@@ -1,5 +1,5 @@
/*
- * TinyMCE Writing Improvement Tool Plugin
+ * TinyMCE Writing Improvement Tool Plugin
* Author: Raphael Mudge (raffi@automattic.com)
*
* http://www.afterthedeadline.com
@@ -15,15 +15,15 @@
* Moxiecode Spell Checker plugin released under the LGPL with TinyMCE
*/
-(function()
+(function()
{
- var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM;
+ var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM;
- tinymce.create('tinymce.plugins.AfterTheDeadlinePlugin',
+ tinymce.create('tinymce.plugins.AfterTheDeadlinePlugin',
{
- getInfo : function()
+ getInfo : function()
{
- return
+ return
({
longname : 'After The Deadline',
author : 'Raphael Mudge',
@@ -40,12 +40,12 @@
core.map = each;
- core.getAttrib = function(node, key)
- {
- return editor.dom.getAttrib(node, key);
+ core.getAttrib = function(node, key)
+ {
+ return editor.dom.getAttrib(node, key);
};
- core.findSpans = function(parent)
+ core.findSpans = function(parent)
{
if (parent == undefined)
return editor.dom.select('span');
@@ -53,39 +53,39 @@
return editor.dom.select('span', parent);
};
- core.hasClass = function(node, className)
- {
- return editor.dom.hasClass(node, className);
+ core.hasClass = function(node, className)
+ {
+ return editor.dom.hasClass(node, className);
};
-
- core.contents = function(node)
- {
- return node.childNodes;
+
+ core.contents = function(node)
+ {
+ return node.childNodes;
};
- core.replaceWith = function(old_node, new_node)
- {
- return editor.dom.replace(new_node, old_node);
+ core.replaceWith = function(old_node, new_node)
+ {
+ return editor.dom.replace(new_node, old_node);
};
- core.create = function(node_html)
- {
+ core.create = function(node_html)
+ {
return editor.dom.create('span', { 'class': 'mceItemHidden' }, node_html);
};
- core.removeParent = function(node)
+ core.removeParent = function(node)
{
editor.dom.remove(node, 1);
return node;
};
- core.remove = function(node)
- {
- editor.dom.remove(node);
+ core.remove = function(node)
+ {
+ editor.dom.remove(node);
};
- core.getLang = function(key, defaultk)
- {
+ core.getLang = function(key, defaultk)
+ {
return editor.getLang("AtD." + key, defaultk);
};
@@ -93,9 +93,9 @@
core.showTypes(editor.getParam("atd_show_types", ""));
return core;
},
-
+
/* called when the plugin is initialized */
- init : function(ed, url)
+ init : function(ed, url)
{
if ( typeof(AtDCore) == 'undefined' )
return;
@@ -118,7 +118,7 @@
}
/* add a command to request a document check and process the results. */
- editor.addCommand('mceWritingImprovementTool', function(callback)
+ editor.addCommand('mceWritingImprovementTool', function(callback)
{
/* checks if a global var for click stats exists and increments it if it does... */
if (typeof AtD_proofread_click_count != "undefined")
@@ -162,7 +162,7 @@
if (results.count > 0)
{
ecount = plugin.markMyWords(results.errors);
- ed.suggestions = results.suggestions;
+ ed.suggestions = results.suggestions;
}
if (ecount == 0 && (!callback || callback == undefined))
@@ -171,9 +171,9 @@
callback(ecount);
});
});
-
+
/* load cascading style sheet for this plugin */
- editor.onInit.add(function()
+ editor.onInit.add(function()
{
/* loading the content.css file, why? I have no clue */
if (editor.settings.content_css !== false)
@@ -189,13 +189,13 @@
editor.onContextMenu.add(plugin._showMenu, plugin);
/* strip out the markup before the contents is serialized (and do it on a copy of the markup so we don't affect the user experience) */
- editor.onPreProcess.add(function(sender, object)
+ editor.onPreProcess.add(function(sender, object)
{
var dom = sender.dom;
- each(dom.select('span', object.node).reverse(), function(n)
+ each(dom.select('span', object.node).reverse(), function(n)
{
- if (n && (dom.hasClass(n, 'hiddenGrammarError') || dom.hasClass(n, 'hiddenSpellError') || dom.hasClass(n, 'hiddenSuggestion') || dom.hasClass(n, 'mceItemHidden') || (dom.getAttrib(n, 'class') == "" && dom.getAttrib(n, 'style') == "" && dom.getAttrib(n, 'id') == "" && !dom.hasClass(n, 'Apple-style-span') && dom.getAttrib(n, 'mce_name') == "")))
+ if (n && (dom.hasClass(n, 'hiddenGrammarError') || dom.hasClass(n, 'hiddenSpellError') || dom.hasClass(n, 'hiddenSuggestion') || dom.hasClass(n, 'mceItemHidden') || (dom.getAttrib(n, 'class') == "" && dom.getAttrib(n, 'style') == "" && dom.getAttrib(n, 'id') == "" && !dom.hasClass(n, 'Apple-style-span') && dom.getAttrib(n, 'mce_name') == "")))
{
dom.remove(n, 1);
}
@@ -203,7 +203,7 @@
});
/* cleanup the HTML before executing certain commands */
- editor.onBeforeExecCommand.add(function(editor, command)
+ editor.onBeforeExecCommand.add(function(editor, command)
{
if (command == 'mceCodeEditor')
{
@@ -214,15 +214,15 @@
plugin._done();
}
});
-
- ed.addButton('AtD', {
+
+ ed.addButton('AtD', {
title: ed.getLang('AtD.button_proofread_tooltip', 'Proofread Writing'),
- image: ed.getParam('atd_button_url', url + '/atdbuttontr.gif'),
+ image: ed.getParam('atd_button_url', url + '/atdbuttontr.gif'),
cmd: 'mceWritingImprovementTool'
});
},
- _removeWords : function(w)
+ _removeWords : function(w)
{
var ed = this.editor, dom = ed.dom, se = ed.selection, b = se.getBookmark();
@@ -247,17 +247,17 @@
return ecount;
},
- _showMenu : function(ed, e)
+ _showMenu : function(ed, e)
{
var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin());
var plugin = this;
- if (!m)
+ if (!m)
{
p1 = DOM.getPos(ed.getContentAreaContainer());
//p2 = DOM.getPos(ed.getContainer());
- m = ed.controlManager.createDropMenu('spellcheckermenu',
+ m = ed.controlManager.createDropMenu('spellcheckermenu',
{
offset_x : p1.x,
offset_y : p1.y,
@@ -292,8 +292,8 @@
(function(sugg)
{
m.add({
- title : sugg,
- onclick : function()
+ title : sugg,
+ onclick : function()
{
ed.core.applySuggestion(e.target, sugg);
t._checkDone();
@@ -304,14 +304,14 @@
m.addSeparator();
}
-
+
if (errorDescription != undefined && errorDescription["moreinfo"] != null)
{
(function(url)
{
m.add({
title : plugin.editor.getLang('AtD.menu_option_explain', 'Explain...'),
- onclick : function()
+ onclick : function()
{
ed.windowManager.open({
url : url,
@@ -328,7 +328,7 @@
m.add({
title : plugin.editor.getLang('AtD.menu_option_ignore_once', 'Ignore suggestion'),
- onclick : function()
+ onclick : function()
{
dom.remove(e.target, 1);
t._checkDone();
@@ -339,7 +339,7 @@
{
m.add({
title : plugin.editor.getLang('AtD.menu_option_ignore_always', 'Ignore always'),
- onclick : function()
+ onclick : function()
{
var url = t.editor.getParam('atd_ignore_rpc_url', '{backend}');
@@ -347,10 +347,10 @@
{
/* Default scheme is to save ignore preferences in a cookie */
- var ignore = tinymce.util.Cookie.getHash('atd_ignore');
+ var ignore = tinymce.util.Cookie.getHash('atd_ignore');
if (ignore == undefined) { ignore = {}; }
ignore[e.target.innerHTML] = 1;
-
+
tinymce.util.Cookie.setHash('atd_ignore', ignore, new Date( (new Date().getTime()) + 157680000000) );
}
else
@@ -370,7 +370,7 @@
},
error : function( type, req, o )
{
- alert( "Ignore preference save failed\n" + type + "\n" + req.status + "\nAt: " + o.url );
+ alert( "Ignore preference save failed\n" + type + "\n" + req.status + "\nAt: " + o.url );
}
});
@@ -387,7 +387,7 @@
{
m.add({
title : plugin.editor.getLang('menu_option_ignore_all', 'Ignore all'),
- onclick : function()
+ onclick : function()
{
t._removeWords(e.target.innerHTML);
t._checkDone();
@@ -401,7 +401,7 @@
m.showMenu(p1.x, p1.y + e.target.offsetHeight - vp.y);
return tinymce.dom.Event.cancel(e);
- }
+ }
else
{
m.hideMenu();
@@ -409,11 +409,11 @@
},
/* loop through editor DOM, call _done if no mce tags exist. */
- _checkDone : function()
+ _checkDone : function()
{
var t = this, ed = t.editor, dom = ed.dom, o;
- each(dom.select('span'), function(n)
+ each(dom.select('span'), function(n)
{
if (n && dom.hasClass(n, 'mceItemHidden'))
{
@@ -429,7 +429,7 @@
},
/* remove all tags, hide the menu, and fire a dom change event */
- _done : function()
+ _done : function()
{
var plugin = this;
plugin._removeWords();
@@ -448,24 +448,24 @@
var url = this.editor.getParam("atd_rpc_url", "{backend}");
var plugin = this;
- if (url == '{backend}' || id == '12345678')
+ if (url == '{backend}' || id == '12345678')
{
this.editor.setProgressState(0);
alert('Please specify: atd_rpc_url and atd_rpc_id');
return;
}
-
+
tinymce.util.XHR.send({
url : url + "/" + file,
content_type : 'text/xml',
type : "POST",
- data : "data=" + encodeURI(data).replace(/&/g, '%26') + "&key=" + id,
+ data : "data=" + encodeURI(data).replace(/&/g, '%26') + "&key=" + id,
async : true,
success : success,
error : function( type, req, o )
{
plugin.editor.setProgressState(0);
- alert( type + "\n" + req.status + "\nAt: " + o.url );
+ alert( type + "\n" + req.status + "\nAt: " + o.url );
}
});
}
diff --git a/plugins/jetpack/modules/carousel.php b/plugins/jetpack/modules/carousel.php
index 2637f43d..e8db24b7 100644
--- a/plugins/jetpack/modules/carousel.php
+++ b/plugins/jetpack/modules/carousel.php
@@ -5,6 +5,7 @@
* Module Description: Transform your standard image galleries into an immersive full-screen experience.
* Sort Order: 4
* First Introduced: 1.5
+ * Requires Connection: No
*/
include dirname( __FILE__ ) . '/carousel/jetpack-carousel.php';
diff --git a/plugins/jetpack/modules/carousel/jetpack-carousel.css b/plugins/jetpack/modules/carousel/jetpack-carousel.css
index 49bdad8e..05854495 100644
--- a/plugins/jetpack/modules/carousel/jetpack-carousel.css
+++ b/plugins/jetpack/modules/carousel/jetpack-carousel.css
@@ -48,7 +48,7 @@ only screen and (min-device-pixel-ratio: 1.5) {
background: #68c9e8; /* Safari */
color: #fff;
}
-
+
.jp-carousel-info ::-moz-selection {
background: #68c9e8; /* Firefox */
color: #fff;
@@ -133,7 +133,7 @@ div.jp-carousel-buttons a {
padding: 5px 2px 5px 0;
text-decoration: none !important;
text-shadow: none !important;
- vertical-align: baseline !important;
+ vertical-align: middle;
-webkit-font-smoothing: subpixel-antialiased;
}
@@ -481,7 +481,7 @@ div#carousel-reblog-box {
display: none;
}
-.jp-carousel-photo-info h1:before,
+.jp-carousel-photo-info h1:before,
.jp-carousel-photo-info h1:after,
.jp-carousel-left-column-wrapper h1:before,
.jp-carousel-left-column-wrapper h1:after {
@@ -693,7 +693,7 @@ textarea#jp-carousel-comment-form-comment-field {
border-radius: 3px;
overflow: hidden;
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
}
@@ -791,7 +791,7 @@ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder
}
#jp-carousel-comment-post-results {
- display: none;
+ display: none;
overflow:auto;
width:100%;
}
@@ -1050,14 +1050,14 @@ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder
margin: 0 10px !important;
}
- .jp-carousel-next-button, .jp-carousel-previous-button {
- display: none !important;
+ .jp-carousel-next-button, .jp-carousel-previous-button {
+ display: none !important;
}
.jp-carousel-buttons {
display: none !important;
}
-
+
.jp-carousel-image-meta {
float: none !important;
width: 100% !important;
@@ -1065,31 +1065,31 @@ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder
-webkit-box-sizing:border-box;
box-sizing: border-box;
}
-
+
.jp-carousel-close-hint {
font-weight: 800 !important;
font-size: 26px !important;
position: fixed !important;
top: -10px;
}
-
+
.jp-carousel-slide img {
filter: alpha(opacity=100);
opacity: 1;
}
-
+
.jp-carousel-wrap {
- background-color: #000;
+ background-color: #000;
}
-
+
.jp-carousel-fadeaway {
display: none;
}
-
+
#jp-carousel-comment-form-container {
display: none !important;
}
-
+
.jp-carousel-titleanddesc {
padding-top: 0 !important;
border: none !important;
@@ -1097,8 +1097,8 @@ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder
.jp-carousel-titleanddesc-title {
font-size: 1em !important;
}
-
+
.jp-carousel-left-column-wrapper {
padding: 0;
- }
+ }
}
diff --git a/plugins/jetpack/modules/carousel/jetpack-carousel.js b/plugins/jetpack/modules/carousel/jetpack-carousel.js
index 43f1d1f7..f101dbf5 100644
--- a/plugins/jetpack/modules/carousel/jetpack-carousel.js
+++ b/plugins/jetpack/modules/carousel/jetpack-carousel.js
@@ -54,9 +54,69 @@ jQuery(document).ready(function($) {
}, 200);
};
- var prepareGallery = function(){
- if (!overlay) {
+ // For each image in the carousel, emit likes widget markup
+ var getCarouselLikeWidgets = function( dataCarouselExtra ) {
+
+ // Only do this if likes is enabled
+ if ( "undefined" === typeof jetpackLikesWidgetQueue )
+ return "";
+
+ var blogId = dataCarouselExtra.likes_blog_id;
+ var attachmentId = 0;
+ var protocol = 'http';
+ var originDomain = 'http://wordpress.com';
+
+ if ( dataCarouselExtra.permalink.length ) {
+ var parts = dataCarouselExtra.permalink.split( ':' );
+ var protocol = parts[0];
+ if ( ( protocol != 'http' ) && ( protocol != 'https' ) ) {
+ protocol = 'http';
+ }
+
+ parts = dataCarouselExtra.permalink.split( '/' );
+ if ( parts.length >= 2 ) {
+ originDomain = protocol + "://" + parts[2];
+ }
+ }
+
+ var likesWidgetContainer = $("<div class='likes-widget-container'></div>");
+
+ $( 'div.gallery, div.tiled-gallery' ).find( 'img' ).each( function() {
+
+ attachmentId = $( this ).attr( "data-attachment-id" );
+ var dataSource = protocol + "://widgets.wp.com/likes/#blog_id=" + blogId + "&amp;post_id=" + attachmentId + "&amp;slim=1&amp;origin=" + originDomain;
+
+ if ( 'en' !== jetpackCarouselStrings.lang ) {
+ dataSource += "&amp;lang=" + jetpackCarouselStrings.lang;
+ }
+
+ var likesWidgetWrapper = $( "<div></div>" );
+ likesWidgetWrapper.addClass( "jetpack-likes-widget-wrapper" )
+ .addClass( "jetpack-likes-widget-unloaded" )
+ .addClass( "slim-likes-widget" )
+ .attr( "id", "like-post-wrapper-" + blogId + "-" + attachmentId )
+ .attr( "data-src", dataSource )
+ .attr( "data-name", "like-post-frame-" + blogId + "-" + attachmentId )
+ .attr( "data-attachment-id", attachmentId )
+ .css( "display", "none" )
+ .css( "vertical-align", "middle" );
+
+ var likesWidget = $( "<iframe class='post-likes-widget jetpack-likes-widget jetpack-resizeable'></iframe>" );
+ likesWidget.attr( "name", "like-post-frame-" + blogId + "-" + attachmentId )
+ .attr( "src", dataSource );
+ likesWidget.css( "display", "inline-block" );
+ likesWidgetWrapper.append( likesWidget );
+
+ likesWidgetWrapper.append( "<div class='post-likes-widget-placeholder'></div>" );
+
+ likesWidgetContainer.append( likesWidgetWrapper );
+ });
+
+ return likesWidgetContainer.html();
+ };
+ var prepareGallery = function( dataCarouselExtra ){
+ if (!overlay) {
overlay = $('<div></div>')
.addClass('jp-carousel-overlay')
.css({
@@ -68,6 +128,9 @@ jQuery(document).ready(function($) {
});
buttons = '<a class="jp-carousel-commentlink" href="#">' + jetpackCarouselStrings.comment + '</a>';
+ if ( 1 == jetpackCarouselStrings.is_logged_in ) {
+ }
+ buttons += getCarouselLikeWidgets( dataCarouselExtra );
buttons = $('<div class="jp-carousel-buttons">' + buttons + '</div>');
caption = $('<h2></h2>');
@@ -81,6 +144,11 @@ jQuery(document).ready(function($) {
'width' : '250px'
});
+ imageMeta.append( buttons );
+ imageMeta.append( "<ul class='jp-carousel-image-exif' style='display:none;'></ul>" );
+ imageMeta.append( "<a class='jp-carousel-image-download' style='display:none;'></a>" );
+ imageMeta.append( "<div class='jp-carousel-image-map' style='display:none;'></div>" );
+
titleAndDescription = $('<div></div>')
.addClass('jp-carousel-titleanddesc')
.css({
@@ -99,15 +167,20 @@ jQuery(document).ready(function($) {
commentFormMarkup += '<iframe src="'+iframeSrc+'" width="100%" height="'+iframeHeight+'" style="width:100%;height:'+iframeHeight+'px;" allowtransparency="true" frameBorder="0" scrolling="no" name="jp-carousel-comment-iframe" id="jp-carousel-comment-iframe"></iframe>';
} else if ( jetpackCarouselStrings.local_comments_commenting_as && jetpackCarouselStrings.local_comments_commenting_as.length ) {
// Jetpack comments not enabled, fallback to local comments
- commentFormMarkup += '<form id="jp-carousel-comment-form">';
- commentFormMarkup += '<textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Write a comment&hellip;"></textarea>';
- commentFormMarkup += '<div id="jp-carousel-comment-form-submit-and-info-wrapper">';
- commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>';
- commentFormMarkup += '<input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="'+jetpackCarouselStrings.post_comment+'" />';
- commentFormMarkup += '<span id="jp-carousel-comment-form-spinner">&nbsp;</span>';
- commentFormMarkup += '<div id="jp-carousel-comment-post-results"></div>';
- commentFormMarkup += '</div>';
- commentFormMarkup += '</form>';
+
+ if ( 1 != jetpackCarouselStrings.is_logged_in && 1 == jetpackCarouselStrings.comment_registration ) {
+ commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>';
+ } else {
+ commentFormMarkup += '<form id="jp-carousel-comment-form">';
+ commentFormMarkup += '<textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Write a comment&hellip;"></textarea>';
+ commentFormMarkup += '<div id="jp-carousel-comment-form-submit-and-info-wrapper">';
+ commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>';
+ commentFormMarkup += '<input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="'+jetpackCarouselStrings.post_comment+'" />';
+ commentFormMarkup += '<span id="jp-carousel-comment-form-spinner">&nbsp;</span>';
+ commentFormMarkup += '<div id="jp-carousel-comment-post-results"></div>';
+ commentFormMarkup += '</div>';
+ commentFormMarkup += '</form>';
+ }
}
commentFormMarkup += '</div>';
@@ -134,10 +207,6 @@ jQuery(document).ready(function($) {
});
leftWidth = ( $(window).width() - ( screenPadding * 2 ) ) - (imageMeta.width() + 40);
- if ( $.browser.mozilla )
- leftWidth -= 55;
- else if ( $.browser.msie )
- leftWidth -= 20;
leftWidth += 'px';
if (isMobile)
@@ -259,6 +328,10 @@ jQuery(document).ready(function($) {
container.animate({scrollTop: parseInt(info.position()['top'], 10)}, 'fast');
$('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast');
$('#jp-carousel-comment-form-comment-field').focus();
+ } else if ( target.hasClass('jp-carousel-comment-login') ) {
+ var url = jetpackCarouselStrings.login_url + '%23jp-carousel-' + attachment_id;
+
+ document.location.href = url;
} else if ( target.parents('#jp-carousel-comment-form-container').length ) {
var textarea = $('#jp-carousel-comment-form-comment-field')
.blur(function(){
@@ -320,12 +393,14 @@ jQuery(document).ready(function($) {
ajaxData['author'] = authorField.val();
ajaxData['url'] = urlField.val();
- if ( ! ajaxData['email'].length || ! ajaxData['email'].match('@') ) {
- gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-email-field', 'error': jetpackCarouselStrings.no_comment_email});
- return;
- } else if ( ! ajaxData['author'].length ) {
- gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-author-field', 'error': jetpackCarouselStrings.no_comment_author});
- return;
+ if ( 1 == jetpackCarouselStrings.require_name_email ) {
+ if ( ! ajaxData['email'].length || ! ajaxData['email'].match('@') ) {
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-email-field', 'error': jetpackCarouselStrings.no_comment_email});
+ return;
+ } else if ( ! ajaxData['author'].length ) {
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-author-field', 'error': jetpackCarouselStrings.no_comment_author});
+ return;
+ }
}
}
@@ -369,8 +444,14 @@ jQuery(document).ready(function($) {
$(window).unbind('keydown', keyListener);
$(window).unbind('resize', resizeListener);
- document.location.hash = '';
$(window).scrollTop(scroll);
+ })
+ .bind('jp_carousel.afterClose', function(){
+ if ( history.pushState ) {
+ history.pushState("", document.title, window.location.pathname + window.location.search);
+ } else {
+ document.location.hash = '';
+ }
gallery.opened = false;
});
@@ -382,6 +463,10 @@ jQuery(document).ready(function($) {
preventDefaultEvents: true
});
+ $( '.jetpack-likes-widget-unloaded' ).each( function() {
+ jetpackLikesWidgetQueue.push( this.id );
+ });
+
nextButton.add(previousButton).click(function(e){
e.preventDefault();
e.stopPropagation();
@@ -397,8 +482,9 @@ jQuery(document).ready(function($) {
var methods = {
testForData: function(gallery) {
gallery = $( gallery ); // make sure we have it as a jQuery object.
- if ( ! gallery.length || undefined == gallery.data( 'carousel-extra' ) )
+ if ( ! gallery.length || undefined == gallery.data( 'carousel-extra' ) ) {
return false;
+ }
return true;
},
@@ -418,8 +504,8 @@ jQuery(document).ready(function($) {
if ( !data )
return; // don't run if the default gallery functions weren't used
- prepareGallery();
-
+ prepareGallery( data );
+
if ( gallery.jp_carousel( 'testIfOpened' ) )
return; // don't open if already opened
@@ -429,8 +515,13 @@ jQuery(document).ready(function($) {
$('body').css('overflow', 'hidden');
// prevent html from overflowing on some of the new themes.
originalHOverflow = $('html').css('overflow');
- $('html').css('overflow', 'hidden');
-
+ $('html').css('overflow', 'hidden');
+
+ // Re-apply inline-block style here and give an initial value for the width
+ // This value will get replaced with a more appropriate value once the slide is loaded
+ // This avoids the likes widget appearing initially full width below the comment button and then shuffling up
+ jQuery( '.slim-likes-widget' ).find( 'iframe' ).css( 'display', 'inline-block' ).css( 'width', '60px' );
+
container.data('carousel-extra', data);
return this.each(function() {
@@ -510,6 +601,10 @@ jQuery(document).ready(function($) {
},
resetButtons : function(current) {
+ if ( current.data('liked') )
+ $('.jp-carousel-buttons a.jp-carousel-like').addClass('liked').text(jetpackCarouselStrings.unlike);
+ else
+ $('.jp-carousel-buttons a.jp-carousel-like').removeClass('liked').text(jetpackCarouselStrings.like);
},
loopSlides : function(reverse){
@@ -604,14 +699,13 @@ jQuery(document).ready(function($) {
gallery.jp_carousel('resetButtons', current);
container.trigger('jp_carousel.selectSlide', [current]);
- $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' ).html('');
-
- gallery.jp_carousel('getTitleDesc', { title: current.data('title'), desc: current.data('desc') } );
- gallery.jp_carousel('getMeta', current.data('image-meta'));
- gallery.jp_carousel('getFullSizeLink', current);
- gallery.jp_carousel('getMap', current.data('image-meta'));
- gallery.jp_carousel('testCommentsOpened', current.data('comments-opened'));
- gallery.jp_carousel('getComments', {'attachment_id': current.data('attachment-id'), 'offset': 0, 'clear': true});
+ gallery.jp_carousel( 'getTitleDesc', { title: current.data( 'title' ), desc: current.data( 'desc' ) } );
+ gallery.jp_carousel( 'updateLikesWidgetVisibility', current.data( 'attachment-id' ) )
+ gallery.jp_carousel( 'updateExif', current.data( 'image-meta' ) );
+ gallery.jp_carousel( 'updateFullSizeLink', current );
+ gallery.jp_carousel( 'updateMap', current.data( 'image-meta' ) );
+ gallery.jp_carousel( 'testCommentsOpened', current.data( 'comments-opened' ) );
+ gallery.jp_carousel( 'getComments', { 'attachment_id': current.data( 'attachment-id' ), 'offset': 0, 'clear': true } );
$('#jp-carousel-comment-post-results').slideUp();
@@ -832,11 +926,11 @@ jQuery(document).ready(function($) {
if ( 'undefined' == typeof args.medium_file || 'undefined' == typeof args.large_file )
return args.orig_file;
- var medium_size = args.medium_file.replace(/^https?:\/\/.+-([\d]+x[\d]+)\..+$/, '$1'),
+ var medium_size = args.medium_file.replace(/-([\d]+x[\d]+)\..+$/, '$1'),
medium_size_parts = (medium_size != args.medium_file) ? medium_size.split('x') : [args.orig_width, 0],
medium_width = parseInt( medium_size_parts[0], 10 ),
medium_height = parseInt( medium_size_parts[1], 10 ),
- large_size = args.large_file.replace(/^https?:\/\/.+-([\d]+x[\d]+)\..+$/, '$1'),
+ large_size = args.large_file.replace(/-([\d]+x[\d]+)\..+$/, '$1'),
large_size_parts = (large_size != args.large_file) ? large_size.split('x') : [args.orig_width, 0],
large_width = parseInt( large_size_parts[0], 10 ),
large_height = parseInt( large_size_parts[1], 10 );
@@ -955,11 +1049,25 @@ jQuery(document).ready(function($) {
$( 'div#jp-carousel-comments-loading' ).css('margin-top', '20px');
},
- getMeta: function( meta ) {
+ updateLikesWidgetVisibility: function( attachmentId ) {
+ // Hide all likes widgets except for the one for the attachmentId passed in
+
+ $( '.jp-carousel-buttons' ).find( '.jetpack-likes-widget-wrapper' ).each( function() {
+ var widgetWrapper = $( this );
+ if ( widgetWrapper.attr('data-attachment-id') == attachmentId ) {
+ widgetWrapper.css( 'display', 'inline-block' );
+ } else {
+ widgetWrapper.css( 'display', 'none' );
+ }
+ });
+ },
+
+ // updateExif updates the contents of the exif UL (.jp-carousel-image-exif)
+ updateExif: function( meta ) {
if ( !meta || 1 != jetpackCarouselStrings.display_exif )
return false;
- var $ul = $( '<ul></ul>' );
+ var $ul = $( "<ul class='jp-carousel-image-exif'></ul>" );
$.each( meta, function( key, val ) {
if ( 0 === parseFloat(val) || !val.length || -1 === $.inArray( key, [ 'camera', 'aperture', 'shutter_speed', 'focal_length' ] ) )
return;
@@ -982,14 +1090,12 @@ jQuery(document).ready(function($) {
$ul.append( '<li><h5>' + jetpackCarouselStrings[key] + '</h5>' + val + '</li>' );
});
- $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' )
- .append( $( buttons ) );
-
- $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' )
- .append( $ul );
+ // Update (replace) the content of the ul
+ $( 'div.jp-carousel-image-meta ul.jp-carousel-image-exif' ).replaceWith( $ul );
},
- getFullSizeLink: function(current) {
+ // updateFullSizeLink updates the contents of the jp-carousel-image-download link
+ updateFullSizeLink: function(current) {
if(!current || !current.data)
return false;
var original = current.data('orig-file').replace(/\?.+$/, ''),
@@ -999,11 +1105,11 @@ jQuery(document).ready(function($) {
.attr( 'href', original )
.attr( 'target', '_blank' );
- $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' )
- .append( permalink );
+ // Update (replace) the content of the anchor
+ $( 'div.jp-carousel-image-meta a.jp-carousel-image-download' ).replaceWith( permalink );
},
- getMap: function( meta ) {
+ updateMap: function( meta ) {
if ( !meta.latitude || !meta.longitude || 1 != jetpackCarouselStrings.display_geo )
return;
@@ -1186,11 +1292,18 @@ jQuery(document).ready(function($) {
// Set an interval on page load to load the carousel if hash exists and not already opened.
// Makes carousel work on page load and when back button leads to same URL with carousel hash (ie: no actual document.ready trigger)
$(document).ready(function(){
+ last_known_location_hash = '';
+
var jp_carousel_open_interval = window.setInterval(function(){
// We should have a URL hash by now.
if ( ! document.location.hash || ! document.location.hash.match(/jp-carousel-(\d+)/) )
return;
+ if ( document.location.hash == last_known_location_hash )
+ return;
+
+ last_known_location_hash = document.location.hash;
+
var gallery = $('div.gallery, div.tiled-gallery'), index = -1, n = document.location.hash.match(/jp-carousel-(\d+)/);
if ( ! $(this).jp_carousel( 'testForData', gallery ) )
diff --git a/plugins/jetpack/modules/carousel/jetpack-carousel.php b/plugins/jetpack/modules/carousel/jetpack-carousel.php
index 314dd7b2..787f177a 100644
--- a/plugins/jetpack/modules/carousel/jetpack-carousel.php
+++ b/plugins/jetpack/modules/carousel/jetpack-carousel.php
@@ -92,9 +92,12 @@ class Jetpack_Carousel {
// Also: not hardcoding path since there is no guarantee site is running on site root in self-hosted context.
$is_logged_in = is_user_logged_in();
$current_user = wp_get_current_user();
+ $comment_registration = intval( get_option( 'comment_registration' ) );
+ $require_name_email = intval( get_option( 'require_name_email' ) );
$localize_strings = array(
'widths' => $this->prebuilt_widths,
'is_logged_in' => $is_logged_in,
+ 'lang' => strtolower( substr( get_locale(), 0, 2 ) ),
'ajaxurl' => admin_url( 'admin-ajax.php', is_ssl() ? 'https' : 'http' ),
'nonce' => wp_create_nonce( 'carousel_nonce' ),
'display_exif' => $this->test_1or0_option( get_option( 'carousel_display_exif' ), true ),
@@ -114,6 +117,9 @@ class Jetpack_Carousel {
'aperture' => __( 'Aperture', 'jetpack' ),
'shutter_speed' => __( 'Shutter Speed', 'jetpack' ),
'focal_length' => __( 'Focal Length', 'jetpack' ),
+ 'comment_registration' => $comment_registration,
+ 'require_name_email' => $require_name_email,
+ 'login_url' => wp_login_url( apply_filters( 'the_permalink', get_permalink() ) ),
);
if ( ! isset( $localize_strings['jetpack_comments_iframe_src'] ) || empty( $localize_strings['jetpack_comments_iframe_src'] ) ) {
@@ -122,13 +128,18 @@ class Jetpack_Carousel {
if ( $is_logged_in ) {
$localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . sprintf( __( 'Commenting as %s', 'jetpack' ), $current_user->data->display_name ) . '</p>';
} else {
- $localize_strings['local_comments_commenting_as'] = ''
- . '<fieldset><label for="email">' . __( 'Email (Required)', 'jetpack' ) . '</label> '
- . '<input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field" /></fieldset>'
- . '<fieldset><label for="author">' . __( 'Name (Required)', 'jetpack' ) . '</label> '
- . '<input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field" /></fieldset>'
- . '<fieldset><label for="url">' . __( 'Website', 'jetpack' ) . '</label> '
- . '<input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field" /></fieldset>';
+ if ( $comment_registration ) {
+ $localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . __( 'You must be <a href="#" class="jp-carousel-comment-login">logged in</a> to post a comment.', 'jetpack' ) . '</p>';
+ } else {
+ $required = ( $require_name_email ) ? __( '%s (Required)', 'jetpack' ) : '%s';
+ $localize_strings['local_comments_commenting_as'] = ''
+ . '<fieldset><label for="email">' . sprintf( $required, __( 'Email', 'jetpack' ) ) . '</label> '
+ . '<input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field" /></fieldset>'
+ . '<fieldset><label for="author">' . sprintf( $required, __( 'Name', 'jetpack' ) ) . '</label> '
+ . '<input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field" /></fieldset>'
+ . '<fieldset><label for="url">' . __( 'Website', 'jetpack' ) . '</label> '
+ . '<input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field" /></fieldset>';
+ }
}
}
@@ -225,7 +236,21 @@ class Jetpack_Carousel {
if ( isset( $post ) ) {
$blog_id = (int) get_current_blog_id();
- $extra_data = array( 'data-carousel-extra' => array( 'blog_id' => $blog_id, 'permalink' => get_permalink( $post->ID ) ) );
+
+ if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $likes_blog_id = $blog_id;
+ } else {
+ $jetpack = Jetpack::init();
+ $likes_blog_id = $jetpack->get_option( 'id' );
+ }
+
+ $extra_data = array(
+ 'data-carousel-extra' => array(
+ 'blog_id' => $blog_id,
+ 'permalink' => get_permalink( $post->ID ),
+ 'likes_blog_id' => $likes_blog_id
+ )
+ );
$extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
foreach ( (array) $extra_data as $data_key => $data_values ) {
@@ -265,11 +290,10 @@ class Jetpack_Carousel {
// Can't just send the results, they contain the commenter's email address.
foreach ( $comments as $comment ) {
- $author_markup = '<a href="' . esc_url( $comment->comment_author_url ) . '">' . esc_html( $comment->comment_author ) . '</a>';
$out[] = array(
'id' => $comment->comment_ID,
'parent_id' => $comment->comment_parent,
- 'author_markup' => $author_markup,
+ 'author_markup' => get_comment_author_link( $comment->comment_ID ),
'gravatar_markup' => get_avatar( $comment->comment_author_email, 64 ),
'date_gmt' => $comment->comment_date_gmt,
'content' => wpautop($comment->comment_content),
@@ -326,23 +350,26 @@ class Jetpack_Carousel {
$email = $_POST['email'];
$url = $_POST['url'];
- if ( empty( $display_name ) )
- die( json_encode( array( 'error' => __( 'Please provide your name.', 'jetpack' ) ) ) );
+ if ( get_option( 'require_name_email' ) ) {
+ if ( empty( $display_name ) )
+ die( json_encode( array( 'error' => __( 'Please provide your name.', 'jetpack' ) ) ) );
- if ( empty( $email ) )
- die( json_encode( array( 'error' => __( 'Please provide an email address.', 'jetpack' ) ) ) );
+ if ( empty( $email ) )
+ die( json_encode( array( 'error' => __( 'Please provide an email address.', 'jetpack' ) ) ) );
- if ( ! is_email( $email ) )
- die( json_encode( array( 'error' => __( 'Please provide a valid email address.', 'jetpack' ) ) ) );
+ if ( ! is_email( $email ) )
+ die( json_encode( array( 'error' => __( 'Please provide a valid email address.', 'jetpack' ) ) ) );
+ }
}
$comment_data = array(
- 'comment_content' => $comment,
- 'comment_post_ID' => $_post_id,
- 'comment_author' => $display_name,
+ 'comment_content' => $comment,
+ 'comment_post_ID' => $_post_id,
+ 'comment_author' => $display_name,
'comment_author_email' => $email,
- 'comment_author_url' => $url,
- 'comment_approved' => 0,
+ 'comment_author_url' => $url,
+ 'comment_approved' => 0,
+ 'comment_type' => '',
);
if ( ! empty( $user_id ) )
diff --git a/plugins/jetpack/modules/carousel/rtl/jetpack-carousel-rtl.css b/plugins/jetpack/modules/carousel/rtl/jetpack-carousel-rtl.css
index 0d010eb5..c34fcfba 100644
--- a/plugins/jetpack/modules/carousel/rtl/jetpack-carousel-rtl.css
+++ b/plugins/jetpack/modules/carousel/rtl/jetpack-carousel-rtl.css
@@ -1,4 +1,4 @@
-/* This file was automatically generated on Jan 29 2013 22:51:19 */
+/* This file was automatically generated on Apr 17 2013 14:28:54 */
* {
line-height:inherit; /* prevent declarations of line-height in the universal selector */
@@ -50,7 +50,7 @@ only screen and (min-device-pixel-ratio: 1.5) {
background: #68c9e8; /* Safari */
color: #fff;
}
-
+
.jp-carousel-info ::-moz-selection {
background: #68c9e8; /* Firefox */
color: #fff;
@@ -135,7 +135,7 @@ div.jp-carousel-buttons a {
padding: 5px 0 5px 2px;
text-decoration: none !important;
text-shadow: none !important;
- vertical-align: baseline !important;
+ vertical-align: middle;
-webkit-font-smoothing: subpixel-antialiased;
}
@@ -483,7 +483,7 @@ div#carousel-reblog-box {
display: none;
}
-.jp-carousel-photo-info h1:before,
+.jp-carousel-photo-info h1:before,
.jp-carousel-photo-info h1:after,
.jp-carousel-left-column-wrapper h1:before,
.jp-carousel-left-column-wrapper h1:after {
@@ -695,7 +695,7 @@ textarea#jp-carousel-comment-form-comment-field {
border-radius: 3px;
overflow: hidden;
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
}
@@ -793,7 +793,7 @@ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder
}
#jp-carousel-comment-post-results {
- display: none;
+ display: none;
overflow:auto;
width:100%;
}
@@ -1052,14 +1052,14 @@ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder
margin: 0 10px !important;
}
- .jp-carousel-next-button, .jp-carousel-previous-button {
- display: none !important;
+ .jp-carousel-next-button, .jp-carousel-previous-button {
+ display: none !important;
}
.jp-carousel-buttons {
display: none !important;
}
-
+
.jp-carousel-image-meta {
float: none !important;
width: 100% !important;
@@ -1067,31 +1067,31 @@ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder
-webkit-box-sizing:border-box;
box-sizing: border-box;
}
-
+
.jp-carousel-close-hint {
font-weight: 800 !important;
font-size: 26px !important;
position: fixed !important;
top: -10px;
}
-
+
.jp-carousel-slide img {
filter: alpha(opacity=100);
opacity: 1;
}
-
+
.jp-carousel-wrap {
- background-color: #000;
+ background-color: #000;
}
-
+
.jp-carousel-fadeaway {
display: none;
}
-
+
#jp-carousel-comment-form-container {
display: none !important;
}
-
+
.jp-carousel-titleanddesc {
padding-top: 0 !important;
border: none !important;
@@ -1099,8 +1099,8 @@ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder
.jp-carousel-titleanddesc-title {
font-size: 1em !important;
}
-
+
.jp-carousel-left-column-wrapper {
padding: 0;
- }
+ }
}
diff --git a/plugins/jetpack/modules/comments.php b/plugins/jetpack/modules/comments.php
index d5d4da4d..26bc504f 100644
--- a/plugins/jetpack/modules/comments.php
+++ b/plugins/jetpack/modules/comments.php
@@ -5,6 +5,7 @@
* Module Description: A new comment system that has integrated social media login options.
* First Introduced: 1.4
* Sort Order: 2
+ * Requires Connection: Yes
*/
require dirname( __FILE__ ) . '/comments/comments.php';
diff --git a/plugins/jetpack/modules/comments/admin.php b/plugins/jetpack/modules/comments/admin.php
index 342b7f64..946f4733 100644
--- a/plugins/jetpack/modules/comments/admin.php
+++ b/plugins/jetpack/modules/comments/admin.php
@@ -30,7 +30,7 @@ class Jetpack_Comments_Settings {
return $instance;
}
-
+
public function __construct( Highlander_Comments_Base $jetpack_comments ) {
$this->jetpack_comments = $jetpack_comments;
diff --git a/plugins/jetpack/modules/comments/base.php b/plugins/jetpack/modules/comments/base.php
index f1b5440e..858b6e3e 100644
--- a/plugins/jetpack/modules/comments/base.php
+++ b/plugins/jetpack/modules/comments/base.php
@@ -102,22 +102,22 @@ class Highlander_Comments_Base {
*/
function comments_array( $comments ) {
global $wpdb, $post;
-
+
$commenter = $this->get_current_commenter();
if ( !$commenter['user_id'] )
return $comments;
-
+
if ( !$commenter['comment_author'] )
return $comments;
-
+
$in_moderation_comments = $wpdb->get_results( $wpdb->prepare(
"SELECT * FROM `$wpdb->comments` WHERE `comment_post_ID` = %d AND `user_id` = 0 AND `comment_author` = %s AND `comment_author_email` = %s AND `comment_approved` = '0' ORDER BY `comment_date_gmt` /* Highlander_Comments_Base::comments_array() */",
$post->ID,
wp_specialchars_decode( $commenter['comment_author'], ENT_QUOTES ),
$commenter['comment_author_email']
) );
-
+
if ( !$in_moderation_comments )
return $comments;
@@ -180,7 +180,7 @@ class Highlander_Comments_Base {
/**
* Allows a logged out user to leave a comment as a facebook or twitter credentialed user.
* Overrides WordPress' core comment_registration option to treat these commenters as "registered" (verified) users.
- *
+ *
* @since JetpackComments (1.4)
* @return If no
*/
@@ -256,12 +256,12 @@ class Highlander_Comments_Base {
if ( empty( $comment ) || is_wp_error( $comment ) ) {
return;
}
-
+
$id_source = $this->is_highlander_comment_post();
if ( empty( $id_source ) ) {
return;
}
-
+
// Set comment author cookies
if ( ( 'wordpress' != $id_source ) && is_user_logged_in() ) {
$comment_cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
diff --git a/plugins/jetpack/modules/comments/comments.php b/plugins/jetpack/modules/comments/comments.php
index 8dae39b7..fa156bb6 100644
--- a/plugins/jetpack/modules/comments/comments.php
+++ b/plugins/jetpack/modules/comments/comments.php
@@ -141,19 +141,19 @@ class Jetpack_Comments extends Highlander_Comments_Base {
// it's not a comment - bail
return $avatar;
}
-
+
if ( false === strpos( $comment->comment_author_url, '/www.facebook.com/' ) && false === strpos( $comment->comment_author_url, '/twitter.com/' ) ) {
// It's neither FB nor Twitter - bail
return $avatar;
}
-
+
// It's a FB or Twitter avatar
$foreign_avatar = get_comment_meta( $comment->comment_ID, 'hc_avatar', true );
if ( empty( $foreign_avatar ) ) {
// Can't find the avatar details - bail
return $avatar;
}
-
+
// Return the FB or Twitter avatar
return preg_replace( '#src=([\'"])[^\'"]+\\1#', 'src=\\1' . esc_url( $this->photon_avatar( $foreign_avatar, $size ) ) . '\\1', $avatar );
}
@@ -184,14 +184,14 @@ class Jetpack_Comments extends Highlander_Comments_Base {
// If users are required to be logged in, and they're not, then we don't need to do anything else
if ( get_option( 'comment_registration' ) && !is_user_logged_in() ) {
- echo '<p id="must-log-in-to-comment">' . sprintf( apply_filters( 'jetpack_must_log_in_to_comment', __( 'You must <a href="%s">log in</a> to post a comment.', 'jetpack' ) ), wp_login_url( get_permalink() . '#respond' ) ) . '</p>';
+ echo '<p class="must-log-in">' . sprintf( apply_filters( 'jetpack_must_log_in_to_comment', __( 'You must <a href="%s">log in</a> to post a comment.', 'jetpack' ) ), wp_login_url( get_permalink() . '#respond' ) ) . '</p>';
return;
}
if ( in_array( 'subscriptions', Jetpack::get_active_modules() ) ) {
$stb_enabled = get_option( 'stb_enabled', 1 );
$stb_enabled = empty( $stb_enabled ) ? 0 : 1;
-
+
$stc_enabled = get_option( 'stc_enabled', 1 );
$stc_enabled = empty( $stc_enabled ) ? 0 : 1;
} else {
@@ -209,6 +209,7 @@ class Jetpack_Comments extends Highlander_Comments_Base {
'show_avatars' => ( get_option( 'show_avatars' ) ? '1' : '0' ),
'avatar_default' => get_option( 'avatar_default' ),
'greeting' => get_option( 'highlander_comment_form_prompt', __( 'Leave a Reply', 'jetpack' ) ),
+ 'greeting_reply' => apply_filters( 'jetpack_comment_form_prompt_reply', __( 'Leave a Reply to %s' , 'jetpack' ) ),
'color_scheme' => get_option( 'jetpack_comment_form_color_scheme', $this->default_color_scheme ),
'lang' => get_bloginfo( 'language' ),
'jetpack_version' => JETPACK__VERSION,
@@ -246,9 +247,11 @@ class Jetpack_Comments extends Highlander_Comments_Base {
// The actual iframe (loads comment form from Jetpack server)
?>
- <div id="respond">
- <div id="cancel-comment-reply-link" style="display:none; float:right;"><a href="#"><?php echo esc_html( __( 'Cancel Reply', 'jetpack' ) ); ?></a></div>
- <iframe src="<?php echo esc_url( $url ); ?>" allowtransparency="<?php echo $transparent; ?>" style="width:100%; height: <?php echo $height; ?>px;border:0px;" frameBorder="0" scrolling="no" name="jetpack_remote_comment" id="jetpack_remote_comment"></iframe>
+ <div id="respond" class="comment-respond">
+ <h3 id="reply-title" class="comment-reply-title"><?php comment_form_title( esc_html( $params['greeting'] ), esc_html( $params['greeting_reply'] ) ); ?> <small><?php cancel_comment_reply_link( esc_html__( 'Cancel reply' , 'jetpack') ); ?></small></h3>
+ <div id="commentform" class="comment-form">
+ <iframe src="<?php echo esc_url( $url ); ?>" allowtransparency="<?php echo $transparent; ?>" style="width:100%; height: <?php echo $height; ?>px;border:0px;" frameBorder="0" scrolling="no" name="jetpack_remote_comment" id="jetpack_remote_comment"></iframe>
+ </div>
</div>
<?php // Below is required for comment reply JS to work ?>
diff --git a/plugins/jetpack/modules/contact-form.php b/plugins/jetpack/modules/contact-form.php
index d53fc4c9..21f409ff 100644
--- a/plugins/jetpack/modules/contact-form.php
+++ b/plugins/jetpack/modules/contact-form.php
@@ -1,9 +1,10 @@
<?php
/**
* Module Name: Contact Form
- * Module Description: Easily insert a contact form any where on your site.
+ * Module Description: Easily insert a contact form anywhere on your site.
* Sort Order: 9
* First Introduced: 1.3
+ * Requires Connection: No
*/
include dirname( __FILE__ ) . '/contact-form/grunion-contact-form.php';
diff --git a/plugins/jetpack/modules/contact-form/admin.php b/plugins/jetpack/modules/contact-form/admin.php
index d3efefa0..5a6af06b 100644
--- a/plugins/jetpack/modules/contact-form/admin.php
+++ b/plugins/jetpack/modules/contact-form/admin.php
@@ -1,21 +1,10 @@
<?php
-function menu_alter() {
- echo '
- <style>
- #menu-posts-feedback .wp-menu-image img { display: none; }
- #adminmenu .menu-icon-feedback:hover div.wp-menu-image, #adminmenu .menu-icon-feedback.wp-has-current-submenu div.wp-menu-image, #adminmenu .menu-icon-feedback.current div.wp-menu-image { background: url("' .GRUNION_PLUGIN_URL . 'images/grunion-menu-hover.png") no-repeat 7px 7px !important; }
- #adminmenu .menu-icon-feedback div.wp-menu-image, #adminmenu .menu-icon-feedback div.wp-menu-image, #adminmenu .menu-icon-feedback div.wp-menu-image { background: url("' . GRUNION_PLUGIN_URL . 'images/grunion-menu.png") no-repeat 7px 7px !important; }
- .grunion-menu-button { background: url("' . GRUNION_PLUGIN_URL . 'images/grunion-form.png") no-repeat; width: 13px; height: 13px; display: inline-block; vertical-align: middle; ) }
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
- #adminmenu .menu-icon-feedback:hover div.wp-menu-image, #adminmenu .menu-icon-feedback.wp-has-current-submenu div.wp-menu-image, #adminmenu .menu-icon-feedback.current div.wp-menu-image { background: url("' .GRUNION_PLUGIN_URL . 'images/grunion-menu-hover-2x.png") no-repeat 7px 7px !important; background-size: 15px 16px !important; }
- #adminmenu .menu-icon-feedback div.wp-menu-image, #adminmenu .menu-icon-feedback div.wp-menu-image, #adminmenu .menu-icon-feedback div.wp-menu-image { background: url("' . GRUNION_PLUGIN_URL . 'images/grunion-menu-2x.png") no-repeat 7px 7px !important; background-size: 15px 16px !important; }
- .grunion-menu-button { background-image: url("' . GRUNION_PLUGIN_URL . 'images/grunion-form-2x.png"); background-size: 13px 12px !important; vertical-align: bottom; }
- }
- </style>';
+function grunion_menu_alter() {
+ wp_enqueue_style( 'grunion-menu-alter', plugins_url( 'css/menu-alter.css', __FILE__ ) );
}
-add_action('admin_head', 'menu_alter');
+add_action( 'admin_enqueue_scripts', 'grunion_menu_alter' );
/**
* Add a contact form button to the post composition screen
@@ -27,8 +16,13 @@ function grunion_media_button( ) {
$title = esc_attr( __( 'Add a custom form', 'jetpack' ) );
$plugin_url = esc_url( GRUNION_PLUGIN_URL );
$site_url = esc_url( admin_url( "/admin-ajax.php?post_id={$iframe_post_id}&action=grunion_form_builder&TB_iframe=true&width=768" ) );
+ ?>
+
+ <a id="insert-jetpack-contact-form" class="button thickbox" title="<?php esc_html_e( 'Add Contact Form', 'jetpack' ); ?>" data-editor="content" href="<?php echo $site_url ?>&id=add_form">
+ <span class="jetpack-contact-form-icon"></span> <?php esc_html_e( 'Add Contact Form', 'jetpack' ); ?>
+ </a>
- echo '<a href="' . $site_url . '&id=add_form" class="thickbox" title="' . $title . '"><div class="grunion-menu-button" alt="' . $title . '"></div></a>';
+ <?php
}
add_action( 'wp_ajax_grunion_form_builder', 'display_form_view' );
@@ -42,14 +36,14 @@ function display_form_view() {
add_action( 'admin_print_styles', 'grunion_admin_css' );
function grunion_admin_css() {
global $current_screen;
- if ( 'edit-feedback' != $current_screen->id )
+ if ( ! in_array( $current_screen->id, array( 'edit-feedback', 'jetpack_page_omnisearch', 'dashboard_page_omnisearch' ) ) )
return;
wp_enqueue_script( 'wp-lists' );
?>
<style type='text/css'>
-.add-new-h2, .view-switch, body.no-js .tablenav select[name^=action], body.no-js #doaction, body.no-js #doaction2 {
+.add-new-h2, .view-switch, body.no-js .tablenav select[name^=action], body.no-js #doaction, body.no-js #doaction2 {
display: none
}
@@ -191,7 +185,7 @@ function grunion_admin_view_tabs( $views ) {
preg_match( '|post_type=feedback\'( class="current")?\>(.*)\<span class=|', $views['all'], $match );
if ( !empty( $match[2] ) )
$views['all'] = str_replace( $match[2], 'Messages ', $views['all'] );
-
+
return $views;
}
@@ -336,7 +330,7 @@ jQuery(document).ready( function($) {
function( r ) {
$('#post-<?php echo $post_id; ?>')
.css( {backgroundColor:'#FF7979'} )
- .fadeOut(350, function() {
+ .fadeOut(350, function() {
$(this).remove();
$('.subsubsub').html(r);
});
@@ -394,7 +388,7 @@ jQuery(document).ready( function($) {
function( r ) {
$('#post-<?php echo $post_id; ?>')
.css( {backgroundColor:'#59C859'} )
- .fadeOut(350, function() {
+ .fadeOut(350, function() {
$(this).remove();
$('.subsubsub').html(r);
});
@@ -473,7 +467,7 @@ function grunion_ajax_shortcode() {
// and constructs a json object representing its contents and attributes
function grunion_ajax_shortcode_to_json() {
global $post, $grunion_form;
-
+
check_ajax_referer( 'grunion_shortcode_to_json' );
if ( !isset( $_POST['content'] ) || !is_numeric( $_POST['post_id'] ) ) {
@@ -583,7 +577,7 @@ function grunion_ajax_spam() {
$sql = "
SELECT post_status,
COUNT( * ) AS post_count
- FROM `{$wpdb->posts}`
+ FROM `{$wpdb->posts}`
WHERE post_type = 'feedback'
GROUP BY post_status
";
@@ -631,3 +625,12 @@ function grunion_ajax_spam() {
echo $status_html;
exit;
}
+
+add_action( 'omnisearch_add_providers', 'grunion_omnisearch_add_providers' );
+function grunion_omnisearch_add_providers() {
+ // Feedback uses capability_type 'page'
+ if ( current_user_can( 'edit_pages' ) ) {
+ require_once( GRUNION_PLUGIN_DIR . '/grunion-omnisearch.php' );
+ new Jetpack_Omnisearch_Grunion;
+ }
+}
diff --git a/plugins/jetpack/modules/contact-form/css/grunion.css b/plugins/jetpack/modules/contact-form/css/grunion.css
index 00035180..d47948b4 100644
--- a/plugins/jetpack/modules/contact-form/css/grunion.css
+++ b/plugins/jetpack/modules/contact-form/css/grunion.css
@@ -1,5 +1,5 @@
.contact-form .clear-form { clear: both; }
-.contact-form input[type='text'], .contact-form input[type='email'] { width: 300px; margin-bottom: 13px; }
+.contact-form input[type='text'], .contact-form input[type='email'] { width: 300px; max-width: 98%; margin-bottom: 13px; }
.contact-form select { margin-bottom: 13px; }
.contact-form textarea { height: 200px; width: 80%; float: none; margin-bottom: 13px; }
.contact-form input[type='radio'], .contact-form input[type='checkbox'] { float: none; margin-bottom: 13px; }
@@ -7,4 +7,4 @@
.contact-form label.checkbox, .contact-form label.radio { margin-bottom: 3px; float: none; font-weight: bold; display: inline-block; }
.contact-form label span { color: #AAA; margin-left: 4px; font-weight: normal; }
.form-errors .form-error-message { color: red; }
-.textwidget input[type='text'], .textwidget input[type='email'], .textwidget textarea { width: 250px; }
+.textwidget input[type='text'], .textwidget input[type='email'], .textwidget textarea { width: 250px; max-width: 98%; }
diff --git a/plugins/jetpack/modules/contact-form/grunion-contact-form.php b/plugins/jetpack/modules/contact-form/grunion-contact-form.php
index 5600febb..76e43be2 100644
--- a/plugins/jetpack/modules/contact-form/grunion-contact-form.php
+++ b/plugins/jetpack/modules/contact-form/grunion-contact-form.php
@@ -67,10 +67,20 @@ class Grunion_Contact_Form_Plugin {
add_action( 'loop_start', array( 'Grunion_Contact_Form', '_style_on' ) );
+ add_action( 'wp_ajax_grunion-contact-form', array( $this, 'ajax_request' ) );
+ add_action( 'wp_ajax_nopriv_grunion-contact-form', array( $this, 'ajax_request' ) );
+
+ // Export to CSV feature
+ if ( is_admin() ) {
+ add_action( 'admin_init', array( $this, 'download_feedback_as_csv' ) );
+ add_action( 'load-edit.php', array( $this, 'export_form' ) );
+ add_action( 'admin_footer', array( $this, 'move_export_form_to_bottom' ) );
+ }
+
// custom post type we'll use to keep copies of the feedback items
register_post_type( 'feedback', array(
'labels' => array(
- 'name' => __( 'Feedbacks', 'jetpack' ),
+ 'name' => __( 'Feedback', 'jetpack' ),
'singular_name' => __( 'Feedback', 'jetpack' ),
'search_items' => __( 'Search Feedback', 'jetpack' ),
'not_found' => __( 'No feedback found', 'jetpack' ),
@@ -98,7 +108,7 @@ class Grunion_Contact_Form_Plugin {
// POST handler
if (
- 'POST' == strtoupper( $_SERVER['REQUEST_METHOD'] )
+ isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' == strtoupper( $_SERVER['REQUEST_METHOD'] )
&&
isset( $_POST['action'] ) && 'grunion-contact-form' == $_POST['action']
&&
@@ -136,9 +146,10 @@ class Grunion_Contact_Form_Plugin {
// It's a form embedded in a text widget
$this->current_widget_id = substr( $id, 7 ); // remove "widget-"
-
+ $widget_type = implode( '-', array_slice( explode( '-', $this->current_widget_id ), 0, -1 ) ); // Remove trailing -#
+
// Is the widget active?
- $sidebar = is_active_widget( false, $this->current_widget_id, 'text' );
+ $sidebar = is_active_widget( false, $this->current_widget_id, $widget_type );
// This is lame - no core API for getting a widget by ID
$widget = isset( $GLOBALS['wp_registered_widgets'][$this->current_widget_id] ) ? $GLOBALS['wp_registered_widgets'][$this->current_widget_id] : false;
@@ -161,12 +172,34 @@ class Grunion_Contact_Form_Plugin {
$form = Grunion_Contact_Form::$last;
- if ( !$form || ( is_wp_error( $form->errors ) && $form->errors->get_error_codes() ) ) {
- return;
- }
+ if ( ! $form )
+ return false;
+
+ if ( is_wp_error( $form->errors ) && $form->errors->get_error_codes() )
+ return $form->errors;
// Process the form
- $form->process_submission();
+ return $form->process_submission();
+ }
+
+ function ajax_request() {
+ $submission_result = self::process_form_submission();
+
+ if ( ! $submission_result ) {
+ header( "HTTP/1.1 500 Server Error", 500, true );
+ echo '<div class="form-error"><ul class="form-errors"><li class="form-error-message">';
+ esc_html_e( 'An error occurred. Please try again later.', 'jetpack' );
+ echo '</li></ul></div>';
+ } elseif ( is_wp_error( $submission_result ) ) {
+ header( "HTTP/1.1 400 Bad Request", 403, true );
+ echo '<div class="form-error"><ul class="form-errors"><li class="form-error-message">';
+ echo esc_html( $submission_result->get_error_message() );
+ echo '</li></ul></div>';
+ } else {
+ echo '<h3>' . esc_html__( 'Message Sent', 'jetpack' ) . '</h3>' . $submission_result;
+ }
+
+ die;
}
/**
@@ -263,7 +296,7 @@ class Grunion_Contact_Form_Plugin {
foreach ( $_SERVER as $k => $value )
if ( !in_array( $k, $ignore ) && is_string( $value ) )
$form["$k"] = $value;
-
+
return $form;
}
@@ -277,7 +310,7 @@ class Grunion_Contact_Form_Plugin {
*/
function is_spam_akismet( $form ) {
global $akismet_api_host, $akismet_api_port;
-
+
if ( !function_exists( 'akismet_http_post' ) )
return false;
@@ -307,6 +340,194 @@ class Grunion_Contact_Form_Plugin {
$response = akismet_http_post( $query_string, $akismet_api_host, "/1.1/submit-{$as}", $akismet_api_port );
return trim( $response[1] );
}
+
+ /**
+ * There aren't any usable actions in core to output the "export feedback" form in the correct place,
+ * so this inline JS moves it from the top of the page to the bottom.
+ */
+ function move_export_form_to_bottom() {
+ if ( get_current_screen()->id != 'edit-feedback' )
+ return;
+
+ // if there aren't any feedbacks, bail out
+ if ( ! (int) wp_count_posts( 'feedback' )->publish )
+ return;
+
+ echo "
+ <script type='text/javascript'>
+ var menu = document.getElementById( 'feedback-export' ),
+ wrapper = document.getElementsByClassName( 'wrap' )[0];
+ wrapper.appendChild(menu);
+ menu.style.display = 'block';
+ </script>
+ ";
+ }
+
+ /**
+ * Prints the menu
+ */
+ function export_form() {
+ if ( get_current_screen()->id != 'edit-feedback' )
+ return;
+
+ // if there aren't any feedbacks, bail out
+ if ( ! (int) wp_count_posts( 'feedback' )->publish )
+ return;
+ ?>
+
+ <div id="feedback-export" style="display:none">
+ <h2><?php _e( 'Export feedback as CSV', 'jetpack' ) ?></h2>
+ <div class="clear"></div>
+ <form action="<?php echo admin_url( 'admin-post.php' ); ?>" method="post" class="form">
+ <?php wp_nonce_field( 'feedback_export','feedback_export_nonce' ); ?>
+
+ <input name="action" value="feedback_export" type="hidden">
+ <label for="post"><? _e( 'Select feedback to download', 'jetpack' ) ?></label>
+ <select name="post">
+ <option value="all"><?php esc_html_e( 'All posts', 'jetpack' ) ?></option>
+ <?php echo $this->get_feedbacks_as_options() ?>
+ </select>
+
+ <br><br>
+ <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_html_e( 'Download', 'jetpack' ); ?>">
+ </form>
+ </div>
+
+ <?php
+ }
+
+ /**
+ * download as a csv a contact form or all of them in a csv file
+ */
+ function download_feedback_as_csv() {
+ if ( empty( $_POST['feedback_export_nonce'] ) )
+ return;
+
+ check_admin_referer( 'feedback_export', 'feedback_export_nonce' );
+
+ $args = array(
+ 'posts_per_page' => -1,
+ 'post_type' => 'feedback',
+ 'post_status' => 'publish',
+ 'meta_key' => '_feedback_subject',
+ 'orderby' => 'meta_value',
+ 'fields' => 'ids',
+ 'suppress_filters' => false,
+ );
+
+ $filename = date( "Y-m-d" ) . '-feedback-export.csv';
+
+ // Check if we want to download all the feedbacks or just a certain contact form
+ if ( ! empty( $_POST['post'] ) && $_POST['post'] !== 'all' ) {
+ $args['post_parent'] = (int) $_POST['post'];
+ $filename = date( "Y-m-d" ) . '-' . str_replace( '&nbsp;', '-', get_the_title( (int) $_POST['post'] ) ) . '.csv';
+ }
+
+ $feedbacks = get_posts( $args );
+ $filename = sanitize_file_name( $filename );
+ $fields = $this->get_field_names( $feedbacks );
+ array_unshift( $fields, __( 'Contact Form', 'jetpack' ) );
+
+ if ( empty( $feedbacks ) )
+ return;
+
+ // Forces the download of the CSV instead of echoing
+ header( 'Content-Disposition: attachment; filename=' . $filename );
+ header( 'Pragma: no-cache' );
+ header( 'Expires: 0' );
+ header( 'Content-Type: text/csv; charset=utf-8' );
+
+ $output = fopen( 'php://output', 'w' );
+
+ // Prints the header
+ fputcsv( $output, $fields );
+
+ // Create the csv string from the array of post ids
+ foreach ( $feedbacks as $feedback ) {
+ fputcsv( $output, self::make_csv_row_from_feedback( $feedback, $fields ) );
+ }
+
+ fclose( $output );
+ }
+
+ /**
+ * Returns a string of HTML <option> items from an array of posts
+ *
+ * @return string a string of HTML <option> items
+ */
+ protected function get_feedbacks_as_options() {
+ $options = '';
+
+ // Get the feedbacks' parents' post IDs
+ $feedbacks = get_posts( array(
+ 'fields' => 'id=>parent',
+ 'posts_per_page' => -1,
+ 'post_type' => 'feedback',
+ 'post_status' => 'publish',
+ 'suppress_filters' => false,
+ ) );
+ $parents = array_unique( array_values( $feedbacks ) );
+
+ $posts = get_posts( array(
+ 'orderby' => 'ID',
+ 'posts_per_page' => -1,
+ 'post_type' => 'any',
+ 'post__in' => array_values( $parents ),
+ 'suppress_filters' => false,
+ ) );
+
+ // creates the string of <option> elements
+ foreach ( $posts as $post ) {
+ $options .= sprintf( '<option value="%s">%s</option>', esc_attr( $post->ID ), esc_html( $post->post_title ) );
+ }
+
+ return $options;
+ }
+
+ /**
+ * Get the names of all the form's fields
+ *
+ * @param array|int $posts the post we want the fields of
+ * @return array the array of fields
+ */
+ protected function get_field_names( $posts ) {
+ $posts = (array) $posts;
+ $all_fields = array();
+
+ foreach ( $posts as $post ){
+ $extra_fields = array_keys( get_post_meta( $post, '_feedback_all_fields', true ) );
+ $all_fields = array_merge( $all_fields, $extra_fields );
+ }
+
+ $all_fields = array_unique( $all_fields );
+ return $all_fields;
+ }
+
+ /**
+ * Creates a valid csv row from a post id
+ *
+ * @param int $post_id The id of the post
+ * @param array $fields An array containing the names of all the fields of the csv
+ * @return String The csv row
+ */
+ protected static function make_csv_row_from_feedback( $post_id, $fields ) {
+ $all_fields = get_post_meta( $post_id, '_feedback_all_fields', true );
+
+ // The first element in all of the exports will be the subject
+ $row_items[] = get_post_meta( $post_id, '_feedback_subject', true );
+
+ // Loop the fields array in order to fill the $row_items array correctly
+ foreach ( $fields as $field ) {
+ if ( $field === __( 'Contact Form', 'jetpack' ) ) // the first field will ever be the contact form, so we can continue
+ continue;
+ elseif ( array_key_exists( $field, $all_fields ) )
+ $row_items[] = $all_fields[$field];
+ else
+ $row_items[] = '';
+ }
+
+ return $row_items;
+ }
}
/**
@@ -520,11 +741,12 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
}
$this->defaults = array(
- 'to' => $default_to,
- 'subject' => $default_subject,
- 'show_subject' => 'no', // only used in back-compat mode
- 'widget' => 0, // Not exposed to the user. Works with Grunion_Contact_Form_Plugin::widget_atts()
- 'id' => null, // Not exposed to the user. Set above.
+ 'to' => $default_to,
+ 'subject' => $default_subject,
+ 'show_subject' => 'no', // only used in back-compat mode
+ 'widget' => 0, // Not exposed to the user. Works with Grunion_Contact_Form_Plugin::widget_atts()
+ 'id' => null, // Not exposed to the user. Set above.
+ 'submit_button_text' => __( 'Submit &#187;', 'jetpack' ),
);
$attributes = shortcode_atts( $this->defaults, $attributes );
@@ -622,7 +844,7 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
$r = '';
$r .= "<div id='contact-form-$id'>\n";
-
+
if ( is_wp_error( $form->errors ) && $form->errors->get_error_codes() ) {
// There are errors. Display them
$r .= "<div class='form-error'>\n<h3>" . __( 'Error!', 'jetpack' ) . "</h3>\n<ul class='form-errors'>\n";
@@ -645,62 +867,7 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
// Don't show the feedback details unless the nonce matches
if ( $feedback_id && wp_verify_nonce( stripslashes( $_GET['_wpnonce'] ), "contact-form-sent-{$feedback_id}" ) ) {
- $feedback = get_post( $feedback_id );
-
- $field_ids = $form->get_field_ids();
-
- // Maps field_ids to post_meta keys
- $field_value_map = array(
- 'name' => 'author',
- 'email' => 'author_email',
- 'url' => 'author_url',
- 'subject' => 'subject',
- 'textarea' => false, // not a post_meta key. This is stored in post_content
- );
-
- $contact_form_message = "<blockquote>\n";
-
- // "Standard" field whitelist
- foreach ( $field_value_map as $type => $meta_key ) {
- if ( isset( $field_ids[$type] ) ) {
- $field = $form->fields[$field_ids[$type]];
-
- if ( $meta_key ) {
- $value = get_post_meta( $feedback_id, "_feedback_{$meta_key}", true );
- } else {
- // The feedback content is stored as the first "half" of post_content
- $value = $feedback->post_content;
- list( $value ) = explode( '<!--more-->', $value );
- $value = trim( $value );
- }
-
- $contact_form_message .= sprintf(
- _x( '%1$s: %2$s', '%1$s = form field label, %2$s = form field value', 'jetpack' ),
- wp_kses( $field->get_attribute( 'label' ), array() ),
- wp_kses( $value, array() )
- ) . '<br />';
- }
- }
-
- // "Non-standard" fields
- if ( $field_ids['extra'] ) {
- // array indexed by field label (not field id)
- $extra_fields = get_post_meta( $feedback_id, '_feedback_extra_fields', true );
-
- foreach ( $field_ids['extra'] as $field_id ) {
- $field = $form->fields[$field_id];
- $label = $field->get_attribute( 'label' );
- $contact_form_message .= sprintf(
- _x( '%1$s: %2$s', '%1$s = form field label, %2$s = form field value', 'jetpack' ),
- wp_kses( $label, array() ),
- wp_kses( $extra_fields[$label], array() )
- ) . '<br />';
- }
- }
-
- $contact_form_message .= "</blockquote><br /><br />";
-
- $r_success_message .= wp_kses( $contact_form_message, array( 'br' => array(), 'blockquote' => array() ) );
+ $r_success_message .= self::success_message( $feedback_id, $form );
}
$r .= apply_filters( 'grunion_contact_form_success_message', $r_success_message );
@@ -721,7 +888,7 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
$r .= "<form action='" . esc_url( $url ) . "' method='post' class='contact-form commentsblock'>\n";
$r .= $form->body;
$r .= "\t<p class='contact-submit'>\n";
- $r .= "\t\t<input type='submit' value='" . esc_attr__( 'Submit &#187;', 'jetpack' ) . "' class='pushbutton-wide'/>\n";
+ $r .= "\t\t<input type='submit' value='" . esc_attr( $form->get_attribute( 'submit_button_text' ) ) . "' class='pushbutton-wide'/>\n";
$r .= "\t\t" . wp_nonce_field( 'contact-form_' . $id, '_wpnonce', true, false ) . "\n"; // nonce and referer
$r .= "\t\t<input type='hidden' name='contact-form-id' value='$id' />\n";
$r .= "\t\t<input type='hidden' name='action' value='grunion-contact-form' />\n";
@@ -734,6 +901,69 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
return $r;
}
+ static function success_message( $feedback_id, $form ) {
+ $r_success_message = '';
+
+ $feedback = get_post( $feedback_id );
+
+ $field_ids = $form->get_field_ids();
+
+ // Maps field_ids to post_meta keys
+ $field_value_map = array(
+ 'name' => 'author',
+ 'email' => 'author_email',
+ 'url' => 'author_url',
+ 'subject' => 'subject',
+ 'textarea' => false, // not a post_meta key. This is stored in post_content
+ );
+
+ $contact_form_message = "<blockquote>\n";
+
+ // "Standard" field whitelist
+ foreach ( $field_value_map as $type => $meta_key ) {
+ if ( isset( $field_ids[$type] ) ) {
+ $field = $form->fields[$field_ids[$type]];
+
+ if ( $meta_key ) {
+ $value = get_post_meta( $feedback_id, "_feedback_{$meta_key}", true );
+ } else {
+ // The feedback content is stored as the first "half" of post_content
+ $value = $feedback->post_content;
+ list( $value ) = explode( '<!--more-->', $value );
+ $value = trim( $value );
+ }
+
+ $contact_form_message .= sprintf(
+ _x( '%1$s: %2$s', '%1$s = form field label, %2$s = form field value', 'jetpack' ),
+ wp_kses( $field->get_attribute( 'label' ), array() ),
+ wp_kses( $value, array() )
+ ) . '<br />';
+ }
+ }
+
+ // "Non-standard" fields
+ if ( $field_ids['extra'] ) {
+ // array indexed by field label (not field id)
+ $extra_fields = get_post_meta( $feedback_id, '_feedback_extra_fields', true );
+
+ foreach ( $field_ids['extra'] as $field_id ) {
+ $field = $form->fields[$field_id];
+ $label = $field->get_attribute( 'label' );
+ $contact_form_message .= sprintf(
+ _x( '%1$s: %2$s', '%1$s = form field label, %2$s = form field value', 'jetpack' ),
+ wp_kses( $label, array() ),
+ wp_kses( $extra_fields[$label], array() )
+ ) . '<br />';
+ }
+ }
+
+ $contact_form_message .= "</blockquote><br /><br />";
+
+ $r_success_message .= wp_kses( $contact_form_message, array( 'br' => array(), 'blockquote' => array() ) );
+
+ return $r_success_message;
+ }
+
/**
* The contact-field shortcode processor
* We use an object method here instead of a static Grunion_Contact_Form_Field class method to parse contact-field shortcodes so that we can tie them to the contact-form object.
@@ -844,7 +1074,7 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
// No one to send it to :(
if ( !$valid_emails ) {
- return;
+ return false;
}
$to = $valid_emails;
@@ -852,11 +1082,11 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
// Make sure we're processing the form we think we're processing... probably a redundant check.
if ( $widget ) {
if ( 'widget-' . $widget != $_POST['contact-form-id'] ) {
- return;
+ return false;
}
} else {
if ( $post->ID != $_POST['contact-form-id'] ) {
- return;
+ return false;
}
}
@@ -937,7 +1167,7 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
// Is it spam?
$is_spam = apply_filters( 'contact_form_is_spam', $akismet_values );
if ( is_wp_error( $is_spam ) ) // WP_Error to abort
- return; // abort
+ return $is_spam; // abort
else if ( $is_spam === TRUE ) // TRUE to flag a spam
$spam = '***SPAM*** ';
@@ -959,14 +1189,16 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
$headers = 'From: ' . $comment_author .' <' . $from_email_addr . ">\r\n" .
'Reply-To: ' . $comment_author . ' <' . $reply_to_addr . ">\r\n" .
- "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"";
+ "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"";
$subject = apply_filters( 'contact_form_subject', $contact_form_subject );
- $time = date_i18n( __( 'l F j, Y \a\t g:i a', 'jetpack' ), current_time( 'timestamp' ) );
-
+ $date_time_format = _x( '%1$s \a\t %2$s', '{$date_format} \a\t {$time_format}', 'jetpack' );
+ $date_time_format = sprintf( $date_time_format, get_option( 'date_format' ), get_option( 'time_format' ) );
+ $time = date_i18n( $date_time_format, current_time( 'timestamp' ) );
+
$extra_content = '';
-
+
foreach ( $extra_values as $label => $value ) {
$extra_content .= $label . ': ' . trim( $value ) . "\n";
}
@@ -1072,6 +1304,10 @@ class Grunion_Contact_Form extends Crunion_Contact_Form_Shortcode {
elseif ( apply_filters( 'grunion_still_email_spam', FALSE ) == TRUE ) // don't send spam by default. Filterable.
wp_mail( $to, "{$spam}{$subject}", $message, $headers );
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
+ return self::success_message( $post_id, $this );
+ }
+
$redirect = wp_get_referer();
if ( !$redirect ) { // wp_get_referer() returns false if the referer is the same as the current page
$redirect = $_SERVER['REQUEST_URI'];
@@ -1168,12 +1404,12 @@ class Grunion_Contact_Form_Field extends Crunion_Contact_Form_Shortcode {
$unescaped_label = preg_replace( '/[^a-zA-Z0-9.-_:]/', '', $unescaped_label );
if ( empty( $id ) ) {
- $id = sanitize_title_with_dashes( 'g' + $form_id . '-' . $unescaped_label );
+ $id = sanitize_title_with_dashes( 'g' . $form_id . '-' . $unescaped_label );
$i = 0;
$max_tries = 24;
while ( isset( $form->fields[$id] ) ) {
$i++;
- $id = sanitize_title_with_dashes( 'g' + $form_id . '-' . $unescaped_label . '-' . $i );
+ $id = sanitize_title_with_dashes( 'g' . $form_id . '-' . $unescaped_label . '-' . $i );
if ( $i > $max_tries ) {
break;
@@ -1320,7 +1556,7 @@ class Grunion_Contact_Form_Field extends Crunion_Contact_Form_Shortcode {
case 'select' :
$r .= "\n<div>\n";
$r .= "\t\t<label for='" . esc_attr( $field_id ) . "' class='grunion-field-label select" . ( $this->is_error() ? ' form-error' : '' ) . "'>" . esc_html( $field_label ) . ( $field_required ? '<span>'. __( "(required)", 'jetpack' ) . '</span>' : '' ) . "</label>\n";
- $r .= "\t<select name='" . esc_attr( $field_id ) . "' id='" . esc_attr( $field_id ) . "' class='select' />\n";
+ $r .= "\t<select name='" . esc_attr( $field_id ) . "' id='" . esc_attr( $field_id ) . "' class='select' >\n";
foreach ( $this->get_attribute( 'options' ) as $option ) {
$option = Grunion_Contact_Form_Plugin::strip_tags( $option );
$r .= "\t\t<option" . selected( $option, $field_value, false ) . ">" . esc_html( $option ) . "</option>\n";
@@ -1328,6 +1564,14 @@ class Grunion_Contact_Form_Field extends Crunion_Contact_Form_Shortcode {
$r .= "\t</select>\n";
$r .= "\t</div>\n";
break;
+ case 'date' :
+ $r .= "\n<div>\n";
+ $r .= "\t\t<label for='" . esc_attr( $field_id ) . "' class='grunion-field-label " . esc_attr( $field_type ) . ( $this->is_error() ? ' form-error' : '' ) . "'>" . esc_html( $field_label ) . ( $field_required ? '<span>' . __( "(required)", 'jetpack' ) . '</span>' : '' ) . "</label>\n";
+ $r .= "\t\t<input type='date' name='" . esc_attr( $field_id ) . "' id='" . esc_attr( $field_id ) . "' value='" . esc_attr( $field_value ) . "' class='" . esc_attr( $field_type ) . "'/>\n";
+ $r .= "\t</div>\n";
+
+ wp_enqueue_script( 'grunion-frontend', plugins_url( 'js/grunion-frontend.js', __FILE__ ), array( 'jquery', 'jquery-ui-datepicker' ) );
+ break;
default : // text field
// note that any unknown types will produce a text input, so we can use arbitrary type names to handle
// input fields like name, email, url that require special validation or handling at POST
@@ -1373,7 +1617,7 @@ function grunion_delete_old_spam() {
# nothing special about 5000 or 11
# just trying to periodically recover deleted rows
$random_num = mt_rand( 1, 5000 );
- if ( apply_filters( 'grunion_optimize_table', ( $random_number == 11 ) ) ) {
+ if ( apply_filters( 'grunion_optimize_table', ( $random_num == 11 ) ) ) {
$wpdb->query( "OPTIMIZE TABLE $wpdb->posts" );
}
diff --git a/plugins/jetpack/modules/contact-form/grunion-form-view.php b/plugins/jetpack/modules/contact-form/grunion-form-view.php
index 836369a8..79d1242a 100644
--- a/plugins/jetpack/modules/contact-form/grunion-form-view.php
+++ b/plugins/jetpack/modules/contact-form/grunion-form-view.php
@@ -72,8 +72,8 @@ wp_localize_script( 'grunion', 'GrunionFB_i18n', array(
#sidemenu a { text-decoration:none; border-top: 1px solid #FFF; display:block; float:left; line-height:28px; padding:0 13px; outline: none; }
#sidemenu a.current { background-color:#F9F9F9; border-color:#DFDFDF #DFDFDF #F9F9F9; color:#D54E21; -moz-border-radius:4px 4px 0 0; border-radius:4px 4px 0 0; -webkit-border-radius:4px 4px 0 0; border-style:solid; border-width:1px; font-weight:normal; }
#sidemenu li { display:inline; margin-bottom:6px; line-height:200%; list-style:none outside none; margin:0; padding:0; text-align:center; white-space:nowrap; }
- .button { background-color:#FFFFFF; background:url("<?php echo get_bloginfo('url'); ?>/wp-admin/images/white-grad.png") repeat-x scroll left top #F2F2F2; border-color:#BBBBBB; min-width:80px; text-align:center; color:#464646; text-shadow:0 1px 0 #FFFFFF; border-style:solid; border-width:1px; cursor:pointer; width: auto; font-size:11px !important; line-height:13px; padding:3px 11px; margin-top: 12px; text-decoration:none; -moz-border-radius:11px; border-radius:11px; -webkit-border-radius:11px }
- .button-primary { background-color:#FFFFFF; font-weight: bold; background: url('<?php echo get_bloginfo('url'); ?>/wp-admin/images/button-grad-active.png') repeat-x scroll left top #21759B; border-color:#298CBA; text-align:center; color:#EAF2FA; text-shadow:0 -1px 0 rgba(0, 0, 0, 0.3); border-style:solid; border-width:1px; cursor:pointer; width: auto; font-size:11px !important; line-height:13px; padding:3px 11px; margin-top: 21px; text-decoration:none; -moz-border-radius:11px; border-radius:11px; -webkit-border-radius:11px }
+ .button { background-color:#f2f2f2; border-color:#BBBBBB; min-width:80px; text-align:center; color:#464646; text-shadow:0 1px 0 #FFFFFF; border-style:solid; border-width:1px; cursor:pointer; width: auto; font-size:11px !important; line-height:13px; padding:3px 11px; margin-top: 12px; text-decoration:none; -moz-border-radius:11px; border-radius:11px; -webkit-border-radius:11px }
+ .button-primary { background-color:#21759B; font-weight: bold; border-color:#298CBA; text-align:center; color:#EAF2FA; text-shadow:0 -1px 0 rgba(0, 0, 0, 0.3); border-style:solid; border-width:1px; cursor:pointer; width: auto; font-size:11px !important; line-height:13px; padding:3px 11px; margin-top: 21px; text-decoration:none; -moz-border-radius:11px; border-radius:11px; -webkit-border-radius:11px }
.clear { clear: both; }
.fb-add-field { padding-left: 10px; }
.fb-add-option { margin: 0 0 14px 100px; }
@@ -132,8 +132,8 @@ wp_localize_script( 'grunion', 'GrunionFB_i18n', array(
); ?></p>
<h3 style="margin-top: 21px;"><?php esc_html_e( 'Can I view my feedback within WordPress?', 'jetpack' ); ?></h3>
<p><?php printf(
- esc_html( _x( 'Yep, you can read your feedback at any time by clicking the "%1$s" link in the admin menu.', '%1$s = "Feedbacks" in an HTML link', 'jetpack' ) ),
- '<a id="fb-feedback" href="' . admin_url( 'edit.php?post_type=feedback' ) . '">' . esc_html__( 'Feedbacks', 'jetpack' ) . '</a>'
+ esc_html( _x( 'Yep, you can read your feedback at any time by clicking the "%1$s" link in the admin menu.', '%1$s = "Feedback" in an HTML link', 'jetpack' ) ),
+ '<a id="fb-feedback" href="' . admin_url( 'edit.php?post_type=feedback' ) . '">' . esc_html__( 'Feedback', 'jetpack' ) . '</a>'
); ?></p>
<div class="clear"></div>
</div>
@@ -144,10 +144,10 @@ wp_localize_script( 'grunion', 'GrunionFB_i18n', array(
</div>
<div id="fb-add-field" style="display: none;">
<h3><?php esc_html_e( 'Edit this new field', 'jetpack' ); ?></h3>
-
+
<label for="fb-new-label"><?php esc_html_e( 'Label', 'jetpack' ); ?></label>
<input type="text" id="fb-new-label" value="<?php esc_attr_e( 'New field', 'jetpack' ); ?>" />
-
+
<label for="fb-new-label"><?php esc_html_e( 'Field type', 'jetpack' ); ?></label>
<select id="fb-new-type">
<option value="checkbox"><?php esc_html_e( 'Checkbox', 'jetpack' ); ?></option>
@@ -160,7 +160,7 @@ wp_localize_script( 'grunion', 'GrunionFB_i18n', array(
<option value="url"><?php esc_html_e( 'Website', 'jetpack' ); ?></option>
</select>
<div class="clear"></div>
-
+
<div id="fb-options" style="display: none;">
<div id="fb-new-options">
<label for="fb-option0"><?php esc_html_e( 'Options', 'jetpack' ); ?></label>
@@ -170,14 +170,14 @@ wp_localize_script( 'grunion', 'GrunionFB_i18n', array(
<a href="#" id="fb-another-option"><?php esc_html_e( 'Add another option', 'jetpack' ); ?></a>
</div>
</div>
-
+
<div class="fb-required">
<label for="fb-new-label"></label>
<input type="checkbox" id="fb-new-required" />
<label for="fb-new-label" class="fb-radio-label"><?php esc_html_e( 'Required?', 'jetpack' ); ?></label>
<div class="clear"></div>
</div>
-
+
<input type="hidden" id="fb-field-id" />
<input type="submit" class="button" value="<?php esc_attr_e( 'Save this field', 'jetpack' ); ?>" id="fb-save-field" name="save">
</div>
@@ -186,9 +186,9 @@ wp_localize_script( 'grunion', 'GrunionFB_i18n', array(
<div id="fb-preview-form" class="fb-container">
<h1><?php esc_html_e( 'Here&#8217;s what your form will look like', 'jetpack' ); ?></h1>
<div id="sortable" class="fb-form-case">
-
+
<div id="fb-extra-fields" class="fb-extra-fields"></div>
-
+
<a href="#" id="fb-new-field" class="fb-add-field"><?php esc_html_e( 'Add a new field', 'jetpack' ); ?></a>
</div>
<input type="submit" class="button-primary" tabindex="4" value="<?php esc_attr_e( 'Add this form to my post', 'jetpack' ); ?>" id="fb-save-form" name="save">
diff --git a/plugins/jetpack/modules/contact-form/js/grunion.js b/plugins/jetpack/modules/contact-form/js/grunion.js
index 835f7f80..bbfd89e3 100644
--- a/plugins/jetpack/modules/contact-form/js/grunion.js
+++ b/plugins/jetpack/modules/contact-form/js/grunion.js
@@ -1,5 +1,5 @@
-if (!window.FB) {
- window.FB = {};
+if ( ! window.FB ) {
+ window.FB = {};
}
GrunionFB_i18n = jQuery.extend( {
@@ -426,7 +426,7 @@ FB.ContactForm = function() {
function showAndHideMessage (message) {
try {
var newMessage = (!message) ? GrunionFB_i18n.savedMessage : message;
- jQuery('#fb-success').html(newMessage);
+ jQuery('#fb-success').text(newMessage);
jQuery('#fb-success').slideDown('fast');
setTimeout(function () {
jQuery('#fb-success').slideUp('fast');
@@ -463,9 +463,9 @@ FB.ContactForm = function() {
var thisLabel = jQuery('#fb-new-label').val();
// Update preview
if (thisLabel.length === 0) {
- jQuery('#fb-new-field' + thisId + ' label .label-text').html("New field");
+ jQuery('#fb-new-field' + thisId + ' label .label-text').text( GrunionFB_i18n.newLabel );
} else {
- jQuery('#fb-new-field' + thisId + ' label .label-text').html(thisLabel);
+ jQuery('#fb-new-field' + thisId + ' label .label-text').text( thisLabel );
}
// Update fbForm object
fbForm.fields[thisId].label = thisLabel;
@@ -493,7 +493,7 @@ FB.ContactForm = function() {
var thisType = jQuery('#fb-new-type').val();
// Update preview
if (thisType === "radio") {
- jQuery('#fb-radio-' + thisId + '-' + thisOptionid + ' span').html(thisOptionValue);
+ jQuery('#fb-radio-' + thisId + '-' + thisOptionid + ' span').text(thisOptionValue);
} else {
jQuery('#fb-' + thisId + '-' + thisOptionid).text(thisOptionValue);
}
@@ -538,7 +538,7 @@ FB.ContactForm = function() {
var isLoaded = thisType;
var thisId = jQuery('#fb-field-id').val();
if (!thisType) { var thisType = jQuery('#fb-new-type').val(); }
- if (!thisLabelText) { var thisLabelText = jQuery('#fb-new-field' + thisId + ' .label-text').html(); }
+ if (!thisLabelText) { var thisLabelText = jQuery('#fb-new-field' + thisId + ' .label-text').text(); }
var isRequired = (thisRequired) ? '<span class="label-required">' + GrunionFB_i18n.requiredLabel + '</span>' : '';
var thisLabel = '<label fieldid="' + thisId + '" for="fb-field' + thisId + '"><span class="label-text">' + FB.esc_html( thisLabelText ) + '</span>' + isRequired + '</label>';
var thisRadio = '<input type="radio" name="radio-' + thisId + '" id="fb-field' + thisId + ' "disabled="disabled" />';
@@ -645,6 +645,8 @@ FB.ContactForm = function() {
content: contentSource
};
+ var $doc = jQuery(document);
+
jQuery.post(ajaxurl, data, function(response) {
// Setup fbForm
parseShortcode(jQuery.parseJSON(response));
@@ -666,7 +668,7 @@ FB.ContactForm = function() {
jQuery('#fb-new-required').click(function () {
updateRequired();
});
- jQuery('.fb-remove').live('click', function () {
+ $doc.on('click', '.fb-remove', function () {
showDesc();
deleteField(jQuery(this));
grabShortcode();
@@ -680,13 +682,13 @@ FB.ContactForm = function() {
hidePopup();
}
});
- jQuery('#fb-another-option').live('click', function () {
+ $doc.on('click', '#fb-another-option', function () {
addOption();
});
- jQuery('.fb-options').live('keyup', function () {
+ $doc.on('keyup', '.fb-options', function () {
updateOption(jQuery(this));
});
- jQuery('.fb-remove-option').live('click', function () {
+ $doc.on('click', '.fb-remove-option', function () {
removeOption(jQuery(this).attr('optionid'));
});
jQuery('#tab-preview a').click(function () {
@@ -708,21 +710,21 @@ FB.ContactForm = function() {
jQuery('#fb-field-subject').blur(function () {
updateSubject();
});
- jQuery('.fb-form-case .fb-new-fields').live('mouseenter', function () {
+ $doc.on('mouseenter', '.fb-form-case .fb-new-fields', function () {
hideShowEditLink('show', jQuery(this));
});
- jQuery('.fb-form-case .fb-new-fields').live('mouseleave', function () {
+ $doc.on('mouseleave', '.fb-form-case .fb-new-fields', function () {
hideShowEditLink('hide');
return false;
});
- jQuery('.fb-edit-field').live('click', function () {
+ $doc.on('click', '.fb-edit-field', function () {
editField(jQuery(this));
return false;
});
- jQuery('.fb-edit-field .fb-reorder').live('click', function () {
+ $doc.on('click', '.fb-edit-field .fb-reorder', function () {
return false;
});
- jQuery('#fb-save-field').live('click', function () {
+ $doc.on('click', '#fb-save-field', function () {
showDesc();
showAndHideMessage();
return false;
diff --git a/plugins/jetpack/modules/custom-css.php b/plugins/jetpack/modules/custom-css.php
index 2b5e6a34..051976a3 100644
--- a/plugins/jetpack/modules/custom-css.php
+++ b/plugins/jetpack/modules/custom-css.php
@@ -5,6 +5,7 @@
* Module Description: Customize the appearance of your site using CSS but without modifying your theme.
* Sort Order: 11
* First Introduced: 1.7
+ * Requires Connection: No
*/
function jetpack_load_custom_css() {
diff --git a/plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php b/plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php
index f458a46e..c5826a0c 100644
--- a/plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php
+++ b/plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php
@@ -736,7 +736,7 @@ class csstidy {
if (empty($this->sub_value_arr)) {
// Quote URLs in imports only if they're not already inside url() and not already quoted.
- if (substr($this->sub_value, 0, 4) != 'url(') {
+ if (substr($this->sub_value, 0, 4) != 'url(') {
if (!($this->sub_value{0} == substr($this->sub_value, -1) && in_array($this->sub_value{0}, array("'", '"')))) {
$this->sub_value = '"' . $this->sub_value . '"';
}
@@ -778,7 +778,7 @@ class csstidy {
}
else {
$this->sub_value = "format(";
-
+
foreach ($format_strings as $format_string) {
$this->sub_value .= '"' . str_replace('"', '\\"', $format_string) . '",';
}
@@ -844,7 +844,7 @@ class csstidy {
$_cur_string = $this->cur_string[count($this->cur_string)-1];
$temp_add = $string{$i};
- // Add another string to the stack. Strings can't be nested inside of quotes, only parentheses, but
+ // Add another string to the stack. Strings can't be nested inside of quotes, only parentheses, but
// parentheticals can be nested more than once.
if ($_str_char === ")" && ($string{$i} === "(" || $string{$i} === '"' || $string{$i} === '\'') && !csstidy::escaped($string, $i)) {
$this->cur_string[] = $string{$i};
@@ -1171,6 +1171,7 @@ class csstidy {
* @version 1.0
*/
function property_is_valid($property) {
+ $property = strtolower($property);
if (in_array(trim($property), $GLOBALS['csstidy']['multiple_properties'])) $property = trim($property);
$all_properties = & $GLOBALS['csstidy']['all_properties'];
return (isset($all_properties[$property]) && strpos($all_properties[$property], strtoupper($this->get_cfg('css_level'))) !== false );
diff --git a/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php b/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php
index 364573a3..2ed9f803 100644
--- a/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php
+++ b/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php
@@ -19,7 +19,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
@@ -262,8 +262,7 @@ class csstidy_optimise {
*/
function compress_important(&$string) {
if (csstidy::is_important($string)) {
- $string = csstidy::gvw_important($string) . '!important';
- }
+ $string = csstidy::gvw_important($string) . ' !important'; }
return $string;
}
@@ -627,7 +626,7 @@ class csstidy_optimise {
// don't try to explose background gradient !
if (stripos($str_value, "gradient(")!==FALSE)
return array('background'=>$str_value);
-
+
$background_prop_default = & $GLOBALS['csstidy']['background_prop_default'];
$repeat = array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space');
$attachment = array('scroll', 'fixed', 'local');
@@ -713,7 +712,7 @@ class csstidy_optimise {
// if background properties is here and not empty, don't try anything
if (isset($input_css['background']) AND $input_css['background'])
return $input_css;
-
+
for ($i = 0; $i < $number_of_values; $i++) {
foreach ($background_prop_default as $bg_property => $default_value) {
// Skip if property does not exist
diff --git a/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_print.php b/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_print.php
index 00a1956b..e2ed97e7 100644
--- a/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_print.php
+++ b/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_print.php
@@ -19,7 +19,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
@@ -312,7 +312,7 @@ class csstidy_print {
elseif ($default_media) {
$this->parser->_add_token(AT_START, $default_media, true);
}
-
+
foreach ($val as $selector => $vali) {
if ($this->parser->get_cfg('sort_properties'))
ksort($vali);
diff --git a/plugins/jetpack/modules/custom-css/csstidy/data-wp.inc.php b/plugins/jetpack/modules/custom-css/csstidy/data-wp.inc.php
index f39ecbf8..de2d0bd6 100644
--- a/plugins/jetpack/modules/custom-css/csstidy/data-wp.inc.php
+++ b/plugins/jetpack/modules/custom-css/csstidy/data-wp.inc.php
@@ -51,6 +51,14 @@ $GLOBALS['csstidy']['at_rules']['-moz-keyframes'] = 'at';
$GLOBALS['csstidy']['at_rules']['-ms-keyframes'] = 'at';
/**
+ * Non-standard viewport rule.
+ */
+$GLOBALS['csstidy']['at_rules']['viewport'] = 'is';
+$GLOBALS['csstidy']['at_rules']['-webkit-viewport'] = 'is';
+$GLOBALS['csstidy']['at_rules']['-moz-viewport'] = 'is';
+$GLOBALS['csstidy']['at_rules']['-ms-viewport'] = 'is';
+
+/**
* Non-standard CSS properties. They're not part of any spec, but we say
* they're in all of them so that we can support them.
*/
diff --git a/plugins/jetpack/modules/custom-css/csstidy/data.inc.php b/plugins/jetpack/modules/custom-css/csstidy/data.inc.php
index c0855681..dfb576d2 100644
--- a/plugins/jetpack/modules/custom-css/csstidy/data.inc.php
+++ b/plugins/jetpack/modules/custom-css/csstidy/data.inc.php
@@ -77,7 +77,7 @@ $GLOBALS['csstidy']['at_rules'] = array('page' => 'is','font-face' => 'is','char
$GLOBALS['csstidy']['unit_values'] = array ('background', 'background-position', 'background-size', 'border', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border-width',
'border-top-width', 'border-right-width', 'border-left-width', 'border-bottom-width', 'bottom', 'border-spacing', 'column-gap', 'column-width',
'font-size', 'height', 'left', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'max-height',
- 'max-width', 'min-height', 'min-width', 'outline', 'outline-width', 'padding', 'padding-top', 'padding-right',
+ 'max-width', 'min-height', 'min-width', 'outline', 'outline-width', 'padding', 'padding-top', 'padding-right',
'padding-bottom', 'padding-left', 'perspective', 'right', 'top', 'text-indent', 'letter-spacing', 'word-spacing', 'width');
/**
@@ -587,7 +587,7 @@ $GLOBALS['csstidy']['quoted_string_properties'] = array('content', 'font', 'font
*
* @global array $GLOBALS['csstidy']['quoted_string_properties']
*/
-$GLOBALS['csstidy']['multiple_properties'] = array_merge( $GLOBALS['csstidy']['unit_values'], array('background', 'background-image', 'transition') );
+$GLOBALS['csstidy']['multiple_properties'] = array_merge( $GLOBALS['csstidy']['color_values'], $GLOBALS['csstidy']['unit_values'], array( 'transition', 'background-image', 'border-image', 'list-style-image' ) );
/**
* An array containing all predefined templates.
diff --git a/plugins/jetpack/modules/custom-css/csstidy/lang.inc.php b/plugins/jetpack/modules/custom-css/csstidy/lang.inc.php
index 9e6b24b0..61f95c7c 100644
--- a/plugins/jetpack/modules/custom-css/csstidy/lang.inc.php
+++ b/plugins/jetpack/modules/custom-css/csstidy/lang.inc.php
@@ -16,7 +16,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
@@ -128,7 +128,7 @@ $lang['de'][15] = 'Standard (Kompromiss zwischen Lesbarkeit und Größe)';
$lang['de'][16] = 'Niedrig (höhere Lesbarkeit)';
$lang['de'][17] = 'Benutzerdefiniert (unten eingeben)';
$lang['de'][18] = 'Benutzerdefinierte <a href="http://csstidy.sourceforge.net/templates.php">Vorlage</a>';
-$lang['de'][19] = 'Optionen';
+$lang['de'][19] = 'Optionen';
$lang['de'][20] = 'Selektoren sortieren (Vorsicht)';
$lang['de'][21] = 'Eigenschaften sortieren';
$lang['de'][22] = 'Selektoren umgruppieren';
@@ -140,7 +140,7 @@ $lang['de'][27] = 'Kleinbuchstaben';
$lang['de'][28] = 'Keine oder ungültige CSS Eingabe oder falsche URL!';
$lang['de'][29] = 'Großbuchstaben';
$lang['de'][30] = 'kleingeschriebene Elementnamen benötigt für XHTML';
-$lang['de'][31] = 'Unnötige Backslashes entfernen';
+$lang['de'][31] = 'Unnötige Backslashes entfernen';
$lang['de'][32] = '!important-Hack konvertieren';
$lang['de'][33] = 'Als Datei ausgeben';
$lang['de'][34] = 'Größere Komprimierung augrund von kleineren Neuezeile-Zeichen';
@@ -271,7 +271,7 @@ $lang['zh'][24] = '壓縮色彩語法';
$lang['zh'][25] = '改用小寫選擇符';
$lang['zh'][26] = '屬性的字形:';
$lang['zh'][27] = '小寫';
-$lang['zh'][28] = '沒有輸入CSS, 語法不符合規定, 或是網址錯誤!';
+$lang['zh'][28] = '沒有輸入CSS, 語法不符合規定, 或是網址錯誤!';
$lang['zh'][29] = '大寫';
$lang['zh'][30] = 'XHTML必須使用小寫的元素名稱';
$lang['zh'][31] = '移除不必要的反斜線';
diff --git a/plugins/jetpack/modules/custom-css/custom-css.php b/plugins/jetpack/modules/custom-css/custom-css.php
index 9bc0c211..02fa7586 100644
--- a/plugins/jetpack/modules/custom-css/custom-css.php
+++ b/plugins/jetpack/modules/custom-css/custom-css.php
@@ -47,6 +47,8 @@ class Jetpack_Custom_CSS {
exit;
}
+ add_action( 'admin_enqueue_scripts', array( 'Jetpack_Custom_CSS', 'enqueue_scripts' ) );
+
if ( isset( $_GET['page'] ) && 'editcss' == $_GET['page'] && is_admin() ) {
// Do migration routine if necessary
Jetpack_Custom_CSS::upgrade();
@@ -56,6 +58,9 @@ class Jetpack_Custom_CSS {
add_action( 'wp_head', array( 'Jetpack_Custom_CSS', 'link_tag' ), 101 );
+ add_filter( 'jetpack_content_width', array( 'Jetpack_Custom_CSS', 'jetpack_content_width' ) );
+ add_filter( 'editor_max_image_size', array( 'Jetpack_Custom_CSS', 'editor_max_image_size' ), 10, 3 );
+
if ( !current_user_can( 'switch_themes' ) && !is_super_admin() )
return;
@@ -65,7 +70,7 @@ class Jetpack_Custom_CSS {
check_admin_referer( 'safecss' );
$save_result = self::save( array(
- 'css' => $_POST['safecss'],
+ 'css' => stripslashes( $_POST['safecss'] ),
'is_preview' => isset( $_POST['action'] ) && $_POST['action'] == 'preview',
'preprocessor' => isset( $_POST['custom_css_preprocessor'] ) ? $_POST['custom_css_preprocessor'] : '',
'add_to_existing' => isset( $_POST['add_to_existing'] ) ? $_POST['add_to_existing'] == 'true' : true,
@@ -108,6 +113,11 @@ class Jetpack_Custom_CSS {
$args = wp_parse_args( $args, $defaults );
+ if ( $args['content_width'] && intval( $args['content_width']) > 0 && ( ! isset( $GLOBALS['content_width'] ) || $args['content_width'] != $GLOBALS['content_width'] ) )
+ $args['content_width'] = intval( $args['content_width'] );
+ else
+ $args['content_width'] = false;
+
// Remove wp_filter_post_kses, this causes CSS escaping issues
remove_filter( 'content_save_pre', 'wp_filter_post_kses' );
remove_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' );
@@ -132,7 +142,7 @@ class Jetpack_Custom_CSS {
$csstidy->set_cfg( 'preserve_css', true );
$csstidy->set_cfg( 'template', dirname( __FILE__ ) . '/csstidy/wordpress-standard.tpl' );
- $css = $orig = stripslashes( $args['css'] );
+ $css = $orig = $args['css'];
$css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $prev = $css );
@@ -161,11 +171,6 @@ class Jetpack_Custom_CSS {
$css = $csstidy->print->plain();
}
- if ( $args['content_width'] && intval( $args['content_width']) > 0 && ( ! isset( $GLOBALS['content_width'] ) || $args['content_width'] != $GLOBALS['content_width'] ) )
- $custom_content_width = intval( $args['content_width'] );
- else
- $custom_content_width = false;
-
if ( $args['add_to_existing'] )
$add_to_existing = 'yes';
else
@@ -179,9 +184,12 @@ class Jetpack_Custom_CSS {
update_option( 'safecss_preview_rev', intval( get_option( 'safecss_preview_rev' ) ) + 1);
update_metadata( 'post', $safecss_revision_id, 'custom_css_add', $add_to_existing );
- update_metadata( 'post', $safecss_revision_id, 'content_width', $custom_content_width );
+ update_metadata( 'post', $safecss_revision_id, 'content_width', $args['content_width'] );
update_metadata( 'post', $safecss_revision_id, 'custom_css_preprocessor', $args['preprocessor'] );
+ delete_option( 'safecss_add' );
+ delete_option( 'safecss_content_width' );
+
if ( $args['is_preview'] ) {
return $safecss_revision_id;
}
@@ -198,12 +206,18 @@ class Jetpack_Custom_CSS {
update_option( 'safecss_rev', intval( get_option( 'safecss_rev' ) ) + 1 );
update_post_meta( $safecss_post_id, 'custom_css_add', $add_to_existing );
- update_post_meta( $safecss_post_id, 'content_width', $custom_content_width );
+ update_post_meta( $safecss_post_id, 'content_width', $args['content_width'] );
update_post_meta( $safecss_post_id, 'custom_css_preprocessor', $args['preprocessor'] );
+
+ delete_option( 'safecss_add' );
+ delete_option( 'safecss_content_width' );
+
update_metadata( 'post', $safecss_post_revision['ID'], 'custom_css_add', $add_to_existing );
- update_metadata( 'post', $safecss_post_revision['ID'], 'content_width', $custom_content_width );
+ update_metadata( 'post', $safecss_post_revision['ID'], 'content_width', $args['content_width'] );
update_metadata( 'post', $safecss_post_revision['ID'], 'custom_css_preprocessor', $args['preprocessor'] );
+ delete_option( 'safecss_preview_add' );
+
return $safecss_post_id;
}
@@ -230,16 +244,16 @@ class Jetpack_Custom_CSS {
$custom_css_post_id = wp_cache_get( 'custom_css_post_id' );
if ( false === $custom_css_post_id ) {
- $custom_css_post = array_shift( get_posts( array(
+ $custom_css_posts = get_posts( array(
'posts_per_page' => 1,
'post_type' => 'safecss',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC'
- ) ) );
+ ) );
- if ( $custom_css_post )
- $custom_css_post_id = $custom_css_post->ID;
+ if ( count( $custom_css_posts ) > 0 )
+ $custom_css_post_id = $custom_css_posts[0]->ID;
else
$custom_css_post_id = 0;
@@ -350,19 +364,35 @@ class Jetpack_Custom_CSS {
}
static function skip_stylesheet() {
- if ( Jetpack_Custom_CSS::is_customizer_preview() ) {
+ $skip_stylesheet = apply_filters( 'safecss_skip_stylesheet', null );
+
+ if ( null !== $skip_stylesheet ) {
+ return $skip_stylesheet;
+ } elseif ( Jetpack_Custom_CSS::is_customizer_preview() ) {
return false;
- }
- else {
+ } else {
if ( Jetpack_Custom_CSS::is_preview() ) {
$safecss_post = Jetpack_Custom_CSS::get_current_revision();
- return (bool) ( get_option( 'safecss_preview_add' ) == 'no' || get_post_meta( $safecss_post['ID'], 'custom_css_add', true ) == 'no' );
+ if ( $safecss_post )
+ return (bool) ( get_post_meta( $safecss_post['ID'], 'custom_css_add', true ) == 'no' );
+ else
+ return (bool) ( get_option( 'safecss_preview_add' ) == 'no' );
}
else {
$custom_css_post_id = Jetpack_Custom_CSS::post_id();
- return (bool) ( get_option( 'safecss_add' ) == 'no' || ( $custom_css_post_id && get_post_meta( $custom_css_post_id, 'custom_css_add', true ) == 'no' ) );
+ if ( $custom_css_post_id ) {
+ $custom_css_add = get_post_meta( $custom_css_post_id, 'custom_css_add', true );
+
+ // It is possible for the CSS to be stored in a post but for the safecss_add option
+ // to have not been upgraded yet if the user hasn't opened their Custom CSS editor
+ // since October 2012.
+ if ( ! empty( $custom_css_add ) )
+ return (bool) ( $custom_css_add === 'no' );
+ }
+
+ return (bool) ( get_option( 'safecss_add' ) == 'no' );
}
}
}
@@ -494,7 +524,7 @@ class Jetpack_Custom_CSS {
if ( $css == '' )
return;
- $href = trailingslashit( site_url() );
+ $href = home_url( '/' );
$href = add_query_arg( 'custom-css', 1, $href );
$href = add_query_arg( 'csblog', $blog_id, $href );
$href = add_query_arg( 'cscache', 6, $href );
@@ -508,6 +538,8 @@ class Jetpack_Custom_CSS {
?>
<link rel="stylesheet" id="custom-css-css" type="text/css" href="<?php echo esc_url( $href ); ?>" />
<?php
+
+ do_action( 'safecss_link_tag_post' );
}
static function style_filter( $current ) {
@@ -571,7 +603,7 @@ class Jetpack_Custom_CSS {
$parent = 'themes.php';
$title = __( 'Edit CSS', 'jetpack' );
$hook = add_theme_page( $title, $title, 'edit_theme_options', 'editcss', array( 'Jetpack_Custom_CSS', 'admin' ) );
- add_action( "admin_print_scripts-$hook", array( 'Jetpack_Custom_CSS', 'enqueue_scripts' ) );
+
add_action( "admin_head-$hook", array( 'Jetpack_Custom_CSS', 'admin_head' ) );
add_action( "load-revision.php", array( 'Jetpack_Custom_CSS', 'prettify_post_revisions' ) );
add_action( "load-$hook", array( 'Jetpack_Custom_CSS', 'update_title' ) );
@@ -588,26 +620,6 @@ class Jetpack_Custom_CSS {
static function prettify_post_revisions() {
add_filter( 'the_title', array( 'Jetpack_Custom_CSS', 'post_title' ), 10, 2 );
- add_action( 'admin_head', array( 'Jetpack_Custom_CSS', 'remove_title_excerpt_from_revisions' ) );
- }
-
- static function remove_title_excerpt_from_revisions() {
- global $post;
-
- if ( !$post ) {
- return;
- }
-
- if ( 'safecss' != $post->post_type ) {
- return;
- }
- ?>
- <style type="text/css">
- #revision-field-post_title, #revision-field-post_excerpt {
- display: none;
- }
- </style>
- <?php
}
static function post_title( $title, $post_id ) {
@@ -626,159 +638,39 @@ class Jetpack_Custom_CSS {
return __( 'Custom CSS Stylesheet', 'jetpack' );
}
- static function enqueue_scripts() {
+ static function enqueue_scripts( $hook ) {
+ if ( 'appearance_page_editcss' != $hook )
+ return;
+
wp_enqueue_script( 'postbox' );
+ wp_enqueue_script( 'custom-css-editor', plugins_url( 'custom-css/js/css-editor.js', __FILE__ ), 'jquery', '20130325', true );
+ wp_enqueue_style( 'custom-css-editor', plugins_url( 'custom-css/css/css-editor.css', __FILE__ ) );
if ( defined( 'SAFECSS_USE_ACE' ) && SAFECSS_USE_ACE ) {
$url = plugins_url( 'custom-css/js/', __FILE__ );
+
wp_enqueue_script( 'jquery.spin' );
wp_enqueue_script( 'safecss-ace', $url . 'ace/ace.js', array(), '20130213', true );
wp_enqueue_script( 'safecss-ace-css', $url . 'ace/mode-css.js', array( 'safecss-ace' ), '20130213', true );
+ wp_enqueue_script( 'safecss-ace-less', $url . 'ace/mode-less.js', array( 'safecss-ace' ), '20130213', true );
+ wp_enqueue_script( 'safecss-ace-scss', $url . 'ace/mode-scss.js', array( 'safecss-ace' ), '20130213', true );
wp_enqueue_script( 'safecss-ace-use', $url . 'safecss-ace.js', array( 'jquery', 'safecss-ace-css' ), '20130213', true );
+
+ wp_enqueue_style( 'custom-css-ace', plugins_url( 'custom-css/css/ace.css', __FILE__ ) );
}
}
static function admin_head() {
- ?>
- <style type="text/css">
- #safecssform {
- position: relative;
- }
-
- #poststuff {
- padding-top: 0;
- }
-
- #safecss {
- min-height: 250px;
- width: 100%;
- }
-
- .misc-pub-section > span {
- font-weight: bold;
- }
-
- .misc-pub-section > div {
- margin-top: 3px;
- }
-
- <?php
-
- if ( defined( 'SAFECSS_USE_ACE' ) && SAFECSS_USE_ACE ) {
-
- ?>
- #safecss-container {
- position: relative;
- width: 99.5%;
- height: 400px;
- border: 1px solid #dfdfdf;
- border-radius: 3px;
- }
-
- #safecss-container .ace_editor {
- font-family: Consolas, Monaco, Courier, monospace;
- }
-
- #safecss-ace {
- width: 100%;
- height: 100%;
- display: none; /* Hide on load otherwise it looks weird */
- }
-
- #safecss-ace.ace_editor {
- display: block;
- }
-
- #safecss-container .ace-tm .ace_gutter {
- background-color: #ededed;
- }
- <?php
- }
-
+ if ( defined( 'SAFECSS_USE_ACE' ) && SAFECSS_USE_ACE ) {
?>
- </style>
- <script type="text/javascript">
- /*<![CDATA[*/
- var safecssResize, safecssInit;
-
+ <script type="text/javascript">
+ /*<![CDATA[*/
+ var SAFECSS_USE_ACE = true;
+ var safecssAceSrcPath = <?php echo json_encode( parse_url( plugins_url( 'custom-css/js/ace/', __FILE__ ), PHP_URL_PATH ) ); ?>;
+ /*]]>*/
+ </script>
<?php
-
- if ( defined( 'SAFECSS_USE_ACE' ) && SAFECSS_USE_ACE ) {
- ?>var safecssAceSrcPath = <?php echo json_encode( parse_url( plugins_url( 'custom-css/js/ace/', __FILE__ ), PHP_URL_PATH ) ); ?>;<?php
- }
-
- ?>
-
- ( function ( $ ) {
- var safe, win;
-
- safecssResize = function () {
- safe.height( win.height() - safe.offset().top - 250 );
- };
-
- safecssInit = function() {
- safe = $('#safecss');
- win = $(window);
-
- postboxes.add_postbox_toggles('editcss');
- safecssResize();
- var button = document.getElementById( 'preview' );
- button.onclick = function ( event ) {
- <?php
-
- // hack for now for previewing.
- // TODO: move all of this JS into its own file.
- if ( defined( 'SAFECSS_USE_ACE' ) && SAFECSS_USE_ACE ) { echo "\t\taceSyncCSS();\n"; }
-
- ?>
- document.forms["safecssform"].target = "csspreview";
- document.forms["safecssform"].action.value = 'preview';
- document.forms["safecssform"].submit();
- document.forms["safecssform"].target = "";
- document.forms["safecssform"].action.value = 'save';
-
- event = event || window.event;
-
- if ( event.preventDefault )
- event.preventDefault();
-
- return false;
- }
- };
-
- window.onresize = safecssResize;
- addLoadEvent( safecssInit );
- } )( jQuery );
-
- jQuery( function ( $ ) {
- $( '.edit-preprocessor' ).bind( 'click', function ( e ) {
- e.preventDefault();
-
- $( '#preprocessor-select' ).slideDown();
- $( this ).hide();
- } );
-
- $( '.cancel-preprocessor' ).bind( 'click', function ( e ) {
- e.preventDefault();
-
- $( '#preprocessor-select' ).slideUp( function () {
- $( '.edit-preprocessor' ).show();
- $( '#preprocessor_choices' ).val( $( '#custom_css_preprocessor' ).val() );
- } );
- } );
-
- $( '.save-preprocessor' ).bind( 'click', function ( e ) {
- e.preventDefault();
-
- $( '#preprocessor-select' ).slideUp();
- $( '#preprocessor-display' ).text( $( '#preprocessor_choices option:selected' ).text() );
- $( '#custom_css_preprocessor' ).val( $( '#preprocessor_choices' ).val() );
- $( '.edit-preprocessor' ).show();
- } );
- } );
- /*]]>*/
- </script>
- <?php
+ }
}
static function saved_message() {
@@ -787,12 +679,12 @@ class Jetpack_Custom_CSS {
static function admin() {
add_meta_box( 'submitdiv', __( 'Publish', 'jetpack' ), array( __CLASS__, 'publish_box' ), 'editcss', 'side' );
+ add_action( 'custom_css_submitbox_misc_actions', array( __CLASS__, 'content_width_settings' ) );
$safecss_post = Jetpack_Custom_CSS::get_post();
if ( ! empty( $safecss_post ) && 0 < $safecss_post['ID'] && wp_get_post_revisions( $safecss_post['ID'] ) )
add_meta_box( 'revisionsdiv', __( 'CSS Revisions', 'jetpack' ), array( __CLASS__, 'revisions_meta_box' ), 'editcss', 'side' );
-
?>
<div class="wrap columns-2">
<?php do_action( 'custom_design_header' ); ?>
@@ -833,6 +725,103 @@ class Jetpack_Custom_CSS {
<?php
}
+ /**
+ * Content width setting callback
+ */
+ static function content_width_settings() {
+ $safecss_post = Jetpack_Custom_CSS::get_current_revision();
+
+ $custom_content_width = get_post_meta( $safecss_post['ID'], 'content_width', true );
+
+ // If custom content width hasn't been overridden and the theme has a content_width value, use that as a default.
+ if ( $custom_content_width <= 0 && ! empty( $GLOBALS['content_width'] ) )
+ $custom_content_width = $GLOBALS['content_width'];
+
+ if ( ! $custom_content_width || ( isset( $GLOBALS['content_width'] ) && $custom_content_width == $GLOBALS['content_width'] ) )
+ $custom_content_width = '';
+
+ ?>
+ <div class="misc-pub-section">
+ <label><?php esc_html_e( 'Content Width:', 'jetpack' ); ?></label>
+ <span id="content-width-display" data-default-text="<?php esc_attr_e( 'Default', 'jetpack' ); ?>" data-custom-text="<?php esc_attr_e( '%s px', 'jetpack' ); ?>"><?php echo $custom_content_width ? sprintf( esc_html__( '%s px', 'jetpack' ), $custom_content_width ) : esc_html_e( 'Default', 'jetpack' ); ?></span>
+ <a class="edit-content-width hide-if-no-js" href="#content-width"><?php echo esc_html_e( 'Edit', 'jetpack' ); ?></a>
+ <div id="content-width-select" class="hide-if-js">
+ <input type="hidden" name="custom_content_width" id="custom_content_width" value="<?php echo esc_attr( $custom_content_width ); ?>" />
+ <p>
+ <?php
+
+ printf(
+ __( 'Limit width to %1$s pixels for videos, full size images, and other shortcodes. (<a href="%2$s">More info</a>.)', 'jetpack' ),
+ '<input type="text" id="custom_content_width_visible" value="' . esc_attr( $custom_content_width ) . '" size="4" />',
+ apply_filters( 'safecss_limit_width_link', 'http://jetpack.me/support/custom-css/#limited-width' )
+ );
+
+ ?>
+ </p>
+ <?php
+
+ if ( !empty( $GLOBALS['content_width'] ) && $custom_content_width != $GLOBALS['content_width'] ) {
+ if ( function_exists( 'wp_get_theme' ) )
+ $current_theme = wp_get_theme()->Name;
+ else
+ $current_theme = get_current_theme();
+
+ ?>
+ <p><?php printf( __( 'The default content width for the %s theme is %d pixels.', 'jetpack' ), $current_theme, intval( $GLOBALS['content_width'] ) ); ?></p>
+ <?php
+ }
+
+ ?>
+ <a class="save-content-width hide-if-no-js button" href="#content-width"><?php esc_html_e( 'OK', 'jetpack' ); ?></a>
+ <a class="cancel-content-width hide-if-no-js" href="#content-width"><?php esc_html_e( 'Cancel', 'jetpack' ); ?></a>
+ </div>
+ <script type="text/javascript">
+ jQuery( function ( $ ) {
+ var defaultContentWidth = <?php echo isset( $GLOBALS['content_width'] ) ? json_encode( intval( $GLOBALS['content_width'] ) ) : 0; ?>;
+
+ $( '.edit-content-width' ).bind( 'click', function ( e ) {
+ e.preventDefault();
+
+ $( '#content-width-select' ).slideDown();
+ $( this ).hide();
+ } );
+
+ $( '.cancel-content-width' ).bind( 'click', function ( e ) {
+ e.preventDefault();
+
+ $( '#content-width-select' ).slideUp( function () {
+ $( '.edit-content-width' ).show();
+ $( '#custom_content_width_visible' ).val( $( '#custom_content_width' ).val() );
+ } );
+ } );
+
+ $( '.save-content-width' ).bind( 'click', function ( e ) {
+ e.preventDefault();
+
+ $( '#content-width-select' ).slideUp();
+
+ var newContentWidth = parseInt( $( '#custom_content_width_visible' ).val(), 10 );
+
+ if ( newContentWidth && newContentWidth != defaultContentWidth ) {
+ $( '#content-width-display' ).text(
+ $( '#content-width-display' )
+ .data( 'custom-text' )
+ .replace( '%s', $( '#custom_content_width_visible' ).val() )
+ );
+ }
+ else {
+ $( '#content-width-display' ).text( $( '#content-width-display' ).data( 'default-text' ) );
+ }
+
+ $( '#custom_content_width' ).val( $( '#custom_content_width_visible' ).val() );
+ $( '.edit-content-width' ).show();
+ } );
+ } );
+ </script>
+ </div>
+ <?php
+ }
+
static function publish_box() {
?>
<div id="minor-publishing">
@@ -897,34 +886,6 @@ class Jetpack_Custom_CSS {
<a class="save-css-mode hide-if-no-js button" href="#css-mode"><?php esc_html_e( 'OK', 'jetpack' ); ?></a>
<a class="cancel-css-mode hide-if-no-js" href="#css-mode"><?php esc_html_e( 'Cancel', 'jetpack' ); ?></a>
</div>
- <script type="text/javascript">
- jQuery( function ( $ ) {
- $( '.edit-css-mode' ).bind( 'click', function ( e ) {
- e.preventDefault();
-
- $( '#css-mode-select' ).slideDown();
- $( this ).hide();
- } );
-
- $( '.cancel-css-mode' ).bind( 'click', function ( e ) {
- e.preventDefault();
-
- $( '#css-mode-select' ).slideUp( function () {
- $( '.edit-css-mode' ).show();
- $( 'input[name=add_to_existing_display][value=' + $( '#add_to_existing' ).val() + ']' ).attr( 'checked', true );
- } );
- } );
-
- $( '.save-css-mode' ).bind( 'click', function ( e ) {
- e.preventDefault();
-
- $( '#css-mode-select' ).slideUp();
- $( '#css-mode-display' ).text( $( 'input[name=add_to_existing_display]:checked' ).val() == 'true' ? 'Add-on' : 'Replacement' );
- $( '#add_to_existing' ).val( $( 'input[name=add_to_existing_display]:checked' ).val() );
- $( '.edit-css-mode' ).show();
- } );
- } );
- </script>
</div>
<?php do_action( 'custom_css_submitbox_misc_actions' ); ?>
</div>
@@ -1012,9 +973,15 @@ class Jetpack_Custom_CSS {
update_post_meta( $safecss_post_id, 'custom_css_add', 'yes' );
update_post_meta( $safecss_post_id, 'content_width', false );
update_post_meta( $safecss_post_id, 'custom_css_preprocessor', '' );
+
+ delete_option( 'safecss_add' );
+ delete_option( 'safecss_content_width' );
+
update_metadata( 'post', $safecss_revision['ID'], 'custom_css_add', 'yes' );
update_metadata( 'post', $safecss_revision['ID'], 'content_width', false );
update_metadata( 'post', $safecss_revision['ID'], 'custom_css_preprocessor', '' );
+
+ delete_option( 'safecss_preview_add' );
}
static function is_customizer_preview() {
@@ -1072,9 +1039,15 @@ class Jetpack_Custom_CSS {
update_metadata( 'post', $safecss_revision['ID'], 'content_width', $content_width );
update_metadata( 'post', $safecss_revision['ID'], 'custom_css_add', $custom_css_add );
update_metadata( 'post', $safecss_revision['ID'], 'custom_css_preprocessor', $preprocessor );
+
+ delete_option( 'safecss_add' );
+ delete_option( 'safecss_content_width' );
+
update_post_meta( $_post->ID, 'content_width', $content_width );
update_post_meta( $_post->ID, 'custom_css_add', $custom_css_add );
update_post_meta( $_post->ID, 'custom_css_preprocessor', $preprocessor );
+
+ delete_option( 'safecss_preview_add' );
}
/**
@@ -1194,6 +1167,40 @@ class Jetpack_Custom_CSS {
return esc_url_raw( $post_link );
}
+
+ /**
+ * When on the edit screen, make sure the custom content width
+ * setting is applied to the large image size.
+ */
+ static function editor_max_image_size( $dims, $size = 'medium', $context = null ) {
+ list( $width, $height ) = $dims;
+
+ if ( 'large' == $size && 'edit' == $context )
+ $width = Jetpack::get_content_width();
+
+ return array( $width, $height );
+ }
+
+ /**
+ * Override the content_width with a custom value if one is set.
+ */
+ static function jetpack_content_width( $content_width ) {
+ $custom_content_width = 0;
+
+ if ( Jetpack_Custom_CSS::is_preview() ) {
+ $safecss_post = Jetpack_Custom_CSS::get_current_revision();
+ $custom_content_width = intval( get_post_meta( $safecss_post['ID'], 'content_width', true ) );
+ } else if ( ! Jetpack_Custom_CSS::is_freetrial() ) {
+ $custom_css_post_id = Jetpack_Custom_CSS::post_id();
+ if ( $custom_css_post_id )
+ $custom_content_width = intval( get_post_meta( $custom_css_post_id, 'content_width', true ) );
+ }
+
+ if ( $custom_content_width > 0 )
+ $content_width = $custom_content_width;
+
+ return $content_width;
+ }
}
class Jetpack_Safe_CSS {
diff --git a/plugins/jetpack/modules/custom-css/custom-css/js/ace/ace.js b/plugins/jetpack/modules/custom-css/custom-css/js/ace/ace.js
index 520b8fca..375915bf 100644
--- a/plugins/jetpack/modules/custom-css/custom-css/js/ace/ace.js
+++ b/plugins/jetpack/modules/custom-css/custom-css/js/ace/ace.js
@@ -8,4 +8,3 @@
ace[key] = a[key];
});
})();
- \ No newline at end of file
diff --git a/plugins/jetpack/modules/custom-css/custom-css/js/ace/worker-css.js b/plugins/jetpack/modules/custom-css/custom-css/js/ace/worker-css.js
index 59ceeaf5..54c2a3e0 100644
--- a/plugins/jetpack/modules/custom-css/custom-css/js/ace/worker-css.js
+++ b/plugins/jetpack/modules/custom-css/custom-css/js/ace/worker-css.js
@@ -1 +1,7886 @@
-"no use strict";function initBaseUrls(e){require.tlns=e}function initSender(){var e=require(null,"ace/lib/event_emitter").EventEmitter,t=require(null,"ace/lib/oop"),n=function(){};return function(){t.implement(this,e),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(n.prototype),new n}if(typeof window!="undefined"&&window.document)throw"atempt to load ace worker into main window instead of webWorker";var console={log:function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},error:function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})}},window={console:console},normalizeModule=function(e,t){if(t.indexOf("!")!==-1){var n=t.split("!");return normalizeModule(e,n[0])+"!"+normalizeModule(e,n[1])}if(t.charAt(0)=="."){var r=e.split("/").slice(0,-1).join("/"),t=r+"/"+t;while(t.indexOf(".")!==-1&&i!=t)var i=t,t=t.replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}return t},require=function(e,t){if(!t.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");var t=normalizeModule(e,t),n=require.modules[t];if(n)return n.initialized||(n.initialized=!0,n.exports=n.factory().exports),n.exports;var r=t.split("/");r[0]=require.tlns[r[0]]||r[0];var i=r.join("/")+".js";return require.id=t,importScripts(i),require(e,t)};require.modules={},require.tlns={};var define=function(e,t,n){arguments.length==2?(n=t,typeof e!="string"&&(t=e,e=require.id)):arguments.length==1&&(n=e,e=require.id);if(e.indexOf("text!")===0)return;var r=function(t,n){return require(e,t,n)};require.modules[e]={factory:function(){var e={exports:{}},t=n(r,e.exports,e);return t&&(e.exports=t),e}}},main,sender;onmessage=function(e){var t=e.data;if(t.command){if(!main[t.command])throw new Error("Unknown command:"+t.command);main[t.command].apply(main,t.args)}else if(t.init){initBaseUrls(t.tlns),require(null,"ace/lib/fixoldbrowsers"),sender=initSender();var n=require(null,t.module)[t.classname];main=new n(sender)}else t.event&&sender&&sender._emit(t.event,t.data)},define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"],function(e,t,n){e("./regexp"),e("./es5-shim")}),define("ace/lib/regexp",["require","exports","module"],function(e,t,n){function o(e){return(e.global?"g":"")+(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":"")}function u(e,t,n){if(Array.prototype.indexOf)return e.indexOf(t,n);for(var r=n||0;r<e.length;r++)if(e[r]===t)return r;return-1}var r={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},i=r.exec.call(/()??/,"")[1]===undefined,s=function(){var e=/^/g;return r.test.call(e,""),!e.lastIndex}();if(s&&i)return;RegExp.prototype.exec=function(e){var t=r.exec.apply(this,arguments),n,a;if(typeof e=="string"&&t){!i&&t.length>1&&u(t,"")>-1&&(a=RegExp(this.source,r.replace.call(o(this),"g","")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;e<arguments.length-2;e++)arguments[e]===undefined&&(t[e]=undefined)}));if(this._xregexp&&this._xregexp.captureNames)for(var f=1;f<t.length;f++)n=this._xregexp.captureNames[f-1],n&&(t[n]=t[f]);!s&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function m(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError;var r=o.call(arguments,1),i=function(){if(this instanceof i){var e=function(){};e.prototype=n.prototype;var s=new e,u=n.apply(s,r.concat(o.call(arguments)));return u!==null&&Object(u)===u?u:s}return n.apply(t,r.concat(o.call(arguments)))};return i});var r=Function.prototype.call,i=Array.prototype,s=Object.prototype,o=i.slice,u=r.bind(s.toString),a=r.bind(s.hasOwnProperty),f,l,c,h,p;if(p=a(s,"__defineGetter__"))f=r.bind(s.__defineGetter__),l=r.bind(s.__defineSetter__),c=r.bind(s.__lookupGetter__),h=r.bind(s.__lookupSetter__);Array.isArray||(Array.isArray=function(t){return u(t)=="[object Array]"}),Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=D(this),r=arguments[1],i=0,s=n.length>>>0;if(u(t)!="[object Function]")throw new TypeError;while(i<s)i in n&&t.call(r,n[i],i,n),i++}),Array.prototype.map||(Array.prototype.map=function(t){var n=D(this),r=n.length>>>0,i=Array(r),s=arguments[1];if(u(t)!="[object Function]")throw new TypeError;for(var o=0;o<r;o++)o in n&&(i[o]=t.call(s,n[o],o,n));return i}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=D(this),r=n.length>>>0,i=[],s=arguments[1];if(u(t)!="[object Function]")throw new TypeError;for(var o=0;o<r;o++)o in n&&t.call(s,n[o],o,n)&&i.push(n[o]);return i}),Array.prototype.every||(Array.prototype.every=function(t){var n=D(this),r=n.length>>>0,i=arguments[1];if(u(t)!="[object Function]")throw new TypeError;for(var s=0;s<r;s++)if(s in n&&!t.call(i,n[s],s,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=D(this),r=n.length>>>0,i=arguments[1];if(u(t)!="[object Function]")throw new TypeError;for(var s=0;s<r;s++)if(s in n&&t.call(i,n[s],s,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=D(this),r=n.length>>>0;if(u(t)!="[object Function]")throw new TypeError;if(!r&&arguments.length==1)throw new TypeError;var i=0,s;if(arguments.length>=2)s=arguments[1];else do{if(i in n){s=n[i++];break}if(++i>=r)throw new TypeError}while(!0);for(;i<r;i++)i in n&&(s=t.call(void 0,s,n[i],i,n));return s}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=D(this),r=n.length>>>0;if(u(t)!="[object Function]")throw new TypeError;if(!r&&arguments.length==1)throw new TypeError;var i,s=r-1;if(arguments.length>=2)i=arguments[1];else do{if(s in n){i=n[s--];break}if(--s<0)throw new TypeError}while(!0);do s in this&&(i=t.call(void 0,i,n[s],s,n));while(s--);return i}),Array.prototype.indexOf||(Array.prototype.indexOf=function(t){var n=D(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=M(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1}),Array.prototype.lastIndexOf||(Array.prototype.lastIndexOf=function(t){var n=D(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,M(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1}),Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:s)});if(!Object.getOwnPropertyDescriptor){var d="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(d+t);if(!a(t,n))return;var r,i,o;r={enumerable:!0,configurable:!0};if(p){var u=t.__proto__;t.__proto__=s;var i=c(t,n),o=h(t,n);t.__proto__=u;if(i||o)return i&&(r.get=i),o&&(r.set=o),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var v;Object.prototype.__proto__===null?v=function(){return{__proto__:null}}:v=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=v();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var g=m({}),y=typeof document=="undefined"||m(document.createElement("div"));if(!g||!y)var b=Object.defineProperty}if(!Object.defineProperty||b){var w="Property description must be an object: ",E="Object.defineProperty called on non-object: ",S="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(E+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(w+r);if(b)try{return b.call(Object,t,n,r)}catch(i){}if(a(r,"value"))if(p&&(c(t,n)||h(t,n))){var o=t.__proto__;t.__proto__=s,delete t[n],t[n]=r.value,t.__proto__=o}else t[n]=r.value;else{if(!p)throw new TypeError(S);a(r,"get")&&f(t,n,r.get),a(r,"set")&&l(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)a(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(x){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(a(t,n))n+="?";t[n]=!0;var r=a(t,n);return delete t[n],r});if(!Object.keys){var T=!0,N=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],C=N.length;for(var k in{toString:null})T=!1;Object.keys=function P(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var P=[];for(var t in e)a(e,t)&&P.push(t);if(T)for(var n=0,r=C;n<r;n++){var i=N[n];a(e,i)&&P.push(i)}return P}}if(!Date.prototype.toISOString||(new Date(-621987552e5)).toISOString().indexOf("-000001")===-1)Date.prototype.toISOString=function(){var t,n,r,i;if(!isFinite(this))throw new RangeError;t=[this.getUTCMonth()+1,this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()],i=this.getUTCFullYear(),i=(i<0?"-":i>9999?"+":"")+("00000"+Math.abs(i)).slice(0<=i&&i<=9999?-4:-6),n=t.length;while(n--)r=t[n],r<10&&(t[n]="0"+r);return i+"-"+t.slice(0,2).join("-")+"T"+t.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"};Date.now||(Date.now=function(){return(new Date).getTime()}),Date.prototype.toJSON||(Date.prototype.toJSON=function(t){if(typeof this.toISOString!="function")throw new TypeError;return this.toISOString()}),Date.parse("+275760-09-13T00:00:00.000Z")!==864e13&&(Date=function(e){var t=function i(t,n,r,s,o,u,a){var f=arguments.length;if(this instanceof e){var l=f==1&&String(t)===t?new e(i.parse(t)):f>=7?new e(t,n,r,s,o,u,a):f>=6?new e(t,n,r,s,o,u):f>=5?new e(t,n,r,s,o):f>=4?new e(t,n,r,s):f>=3?new e(t,n,r):f>=2?new e(t,n):f>=1?new e(t):new e;return l.constructor=i,l}return e.apply(this,arguments)},n=new RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{3}))?)?(?:Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$");for(var r in e)t[r]=e[r];return t.now=e.now,t.UTC=e.UTC,t.prototype=e.prototype,t.prototype.constructor=t,t.parse=function(r){var i=n.exec(r);if(i){i.shift();for(var s=1;s<7;s++)i[s]=+(i[s]||(s<3?1:0)),s==1&&i[s]--;var o=+i.pop(),u=+i.pop(),a=i.pop(),f=0;if(a){if(u>23||o>59)return NaN;f=(u*60+o)*6e4*(a=="+"?-1:1)}var l=+i[0];return 0<=l&&l<=99?(i[0]=l+400,e.UTC.apply(this,i)+f-126227808e5):e.UTC.apply(this,i)+f}return e.parse.apply(this,arguments)},t}(Date));var L=" \n \f\r   ᠎              \u2028\u2029";if(!String.prototype.trim||L.trim()){L="["+L+"]";var A=new RegExp("^"+L+L+"*"),O=new RegExp(L+L+"*$");String.prototype.trim=function(){return String(this).replace(A,"").replace(O,"")}}var M=function(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e},_="a"[0]!="a",D=function(e){if(e==null)throw new TypeError;return _&&typeof e=="string"&&e?e.split(""):Object(e)}}),define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){var r={};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry=this._eventRegistry||{},this._defaultHandlers=this._defaultHandlers||{};var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=function(){this.propagationStopped=!0}),t.preventDefault||(t.preventDefault=function(){this.defaultPrevented=!0});for(var i=0;i<n.length;i++){n[i](t);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t)},r.setDefaultHandler=function(e,t){this._defaultHandlers=this._defaultHandlers||{};if(this._defaultHandlers[e])throw new Error("The default handler for '"+e+"' is already set");this._defaultHandlers[e]=t},r.on=r.addEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];n||(n=this._eventRegistry[e]=[]),n.indexOf(t)==-1&&n.push(t)},r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),define("ace/lib/oop",["require","exports","module"],function(e,t,n){t.inherits=function(){var e=function(){};return function(t,n){e.prototype=n.prototype,t.super_=n.prototype,t.prototype=new e,t.prototype.constructor=t}}(),t.mixin=function(e,t){for(var n in t)e[n]=t[n]},t.implement=function(e,n){t.mixin(e,n)}}),define("ace/mode/css_worker",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/worker/mirror","ace/mode/css/csslint"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/lang"),s=e("../worker/mirror").Mirror,o=e("./css/csslint").CSSLint,u=t.Worker=function(e){s.call(this,e),this.setTimeout(400),this.ruleset=null,this.setDisabledRules("ids"),this.setInfoRules("adjoining-classes|qualified-headings|zero-units|gradients|import|outline-none")};r.inherits(u,s),function(){this.setInfoRules=function(e){typeof e=="string"&&(e=e.split("|")),this.infoRules=i.arrayToMap(e),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.setDisabledRules=function(e){if(!e)this.ruleset=null;else{typeof e=="string"&&(e=e.split("|"));var t={};o.getRules().forEach(function(e){t[e.id]=!0}),e.forEach(function(e){delete t[e]}),console.log(t),this.ruleset=t}this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.onUpdate=function(){var e=this.doc.getValue(),t=this.infoRules,n=o.verify(e,this.ruleset);this.sender.emit("csslint",n.messages.map(function(e){return{row:e.line-1,column:e.col-1,text:e.message,type:t[e.rule.id]?"info":e.type}}))}}.call(u.prototype)}),define("ace/lib/lang",["require","exports","module"],function(e,t,n){t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){return(new Array(t+1)).join(e)};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object")return e;var t=e.constructor();for(var n in e)typeof e[n]=="object"?t[n]=this.deepCopy(e[n]):t[n]=e[n];return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)};return i.delay=i,i.schedule=function(e){n==null&&(n=setTimeout(r,e||0))},i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.deferredCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas([e.data]),n.schedule(s.$timeout)})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){}}).call(s.prototype)}),define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length==0?this.$lines=[""]:Array.isArray(e)?this.insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length==0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);t?this.$autoNewLine=t[1]:this.$autoNewLine="\n"},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";case"auto":return this.$autoNewLine}},this.$autoNewLine="\n",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.$lines[e.start.row].substring(e.start.column,e.end.column);var t=this.getLines(e.start.row+1,e.end.row-1);return t.unshift((this.$lines[e.start.row]||"").substring(e.start.column)),t.push((this.$lines[e.end.row]||"").substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t&&(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this.insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){if(t.length==0)return{row:e,column:0};if(t.length>65535){var n=this.insertLines(e,t.slice(65535));t=t.slice(0,65535)}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._emit("change",{data:o}),n||i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._emit("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._emit("change",{data:i}),r},this.remove=function(e){e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this.removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._emit("change",{data:a}),r.start},this.removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._emit("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._emit("change",{data:o})},this.replace=function(e,t){if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this.removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this.insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}}}).call(u.prototype),t.Document=u}),define("ace/range",["require","exports","module"],function(e,t,n){var r=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row==e.start.row&&this.end.row==e.end.row&&this.start.column==e.start.column&&this.end.column==e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};if(this.start.row>t)var i={row:t+1,column:0};if(this.start.row<e)var i={row:e,column:0};if(this.end.row<e)var n={row:e,column:0};return r.fromPoints(i||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var i={row:e,column:t};else var s={row:e,column:t};return r.fromPoints(i||this.start,s||this.end)},this.isEmpty=function(){return this.start.row==this.end.row&&this.start.column==this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return r.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new r(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new r(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new r(t.row,t.column,n.row,n.column)}}).call(r.prototype),r.fromPoints=function(e,t){return new r(e.row,e.column,t.row,t.column)},t.Range=r}),define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.document=e,typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n),this.$onChange=this.onChange.bind(this),e.on("change",this.$onChange)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column;t.action==="insertText"?n.start.row===r&&n.start.column<=i?n.start.row===n.end.row?i+=n.end.column-n.start.column:(i-=n.start.column,r+=n.end.row-n.start.row):n.start.row!==n.end.row&&n.start.row<r&&(r+=n.end.row-n.start.row):t.action==="insertLines"?n.start.row<=r&&(r+=n.end.row-n.start.row):t.action=="removeText"?n.start.row==r&&n.start.column<i?n.end.column>=i?i=n.start.column:i=Math.max(0,i-(n.end.column-n.start.column)):n.start.row!==n.end.row&&n.start.row<r?(n.end.row==r&&(i=Math.max(0,i-n.end.column)+n.start.column),r-=n.end.row-n.start.row):n.end.row==r&&(r-=n.end.row-n.start.row,i=Math.max(0,i-n.end.column)+n.start.column):t.action=="removeLines"&&n.start.row<=r&&(n.end.row<=r?r-=n.end.row-n.start.row:(r=n.start.row,i=0)),this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._emit("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),define("ace/mode/css/csslint",["require","exports","module"],function(require,exports,module){function Reporter(e,t){this.messages=[],this.stats=[],this.lines=e,this.ruleset=t}var parserlib={};(function(){function e(){this._listeners={}}function t(e){this._input=e.replace(/\n\r?/g,"\n"),this._line=1,this._col=1,this._cursor=0}function n(e,t,n){this.col=n,this.line=t,this.message=e}function r(e,t,n,r){this.col=n,this.line=t,this.text=e,this.type=r}function i(e,n){this._reader=e?new t(e.toString()):null,this._token=null,this._tokenData=n,this._lt=[],this._ltIndex=0,this._ltIndexCache=[]}e.prototype={constructor:e,addListener:function(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t)},fire:function(e){typeof e=="string"&&(e={type:e}),typeof e.target!="undefined"&&(e.target=this);if(typeof e.type=="undefined")throw new Error("Event object missing 'type' property.");if(this._listeners[e.type]){var t=this._listeners[e.type].concat();for(var n=0,r=t.length;n<r;n++)t[n].call(this,e)}},removeListener:function(e,t){if(this._listeners[e]){var n=this._listeners[e];for(var r=0,i=n.length;r<i;r++)if(n[r]===t){n.splice(r,1);break}}}},t.prototype={constructor:t,getCol:function(){return this._col},getLine:function(){return this._line},eof:function(){return this._cursor==this._input.length},peek:function(e){var t=null;return e=typeof e=="undefined"?1:e,this._cursor<this._input.length&&(t=this._input.charAt(this._cursor+e-1)),t},read:function(){var e=null;return this._cursor<this._input.length&&(this._input.charAt(this._cursor)=="\n"?(this._line++,this._col=1):this._col++,e=this._input.charAt(this._cursor++)),e},mark:function(){this._bookmark={cursor:this._cursor,line:this._line,col:this._col}},reset:function(){this._bookmark&&(this._cursor=this._bookmark.cursor,this._line=this._bookmark.line,this._col=this._bookmark.col,delete this._bookmark)},readTo:function(e){var t="",n;while(t.length<e.length||t.lastIndexOf(e)!=t.length-e.length){n=this.read();if(!n)throw new Error('Expected "'+e+'" at line '+this._line+", col "+this._col+".");t+=n}return t},readWhile:function(e){var t="",n=this.read();while(n!==null&&e(n))t+=n,n=this.read();return t},readMatch:function(e){var t=this._input.substring(this._cursor),n=null;return typeof e=="string"?t.indexOf(e)===0&&(n=this.readCount(e.length)):e instanceof RegExp&&e.test(t)&&(n=this.readCount(RegExp.lastMatch.length)),n},readCount:function(e){var t="";while(e--)t+=this.read();return t}},n.prototype=new Error,r.fromToken=function(e){return new r(e.value,e.startLine,e.startCol)},r.prototype={constructor:r,valueOf:function(){return this.toString()},toString:function(){return this.text}},i.createTokenData=function(e){var t=[],n={},r=e.concat([]),i=0,s=r.length+1;r.UNKNOWN=-1,r.unshift({name:"EOF"});for(;i<s;i++)t.push(r[i].name),r[r[i].name]=i,r[i].text&&(n[r[i].text]=i);return r.name=function(e){return t[e]},r.type=function(e){return n[e]},r},i.prototype={constructor:i,match:function(e,t){e instanceof Array||(e=[e]);var n=this.get(t),r=0,i=e.length;while(r<i)if(n==e[r++])return!0;return this.unget(),!1},mustMatch:function(e,t){var r;e instanceof Array||(e=[e]);if(!this.match.apply(this,arguments))throw r=this.LT(1),new n("Expected "+this._tokenData[e[0]].name+" at line "+r.startLine+", col "+r.startCol+".",r.startLine,r.startCol)},advance:function(e,t){while(this.LA(0)!==0&&!this.match(e,t))this.get();return this.LA(0)},get:function(e){var t=this._tokenData,n=this._reader,r,i=0,s=t.length,o=!1,u,a;if(this._lt.length&&this._ltIndex>=0&&this._ltIndex<this._lt.length){i++,this._token=this._lt[this._ltIndex++],a=t[this._token.type];while(a.channel!==undefined&&e!==a.channel&&this._ltIndex<this._lt.length)this._token=this._lt[this._ltIndex++],a=t[this._token.type],i++;if((a.channel===undefined||e===a.channel)&&this._ltIndex<=this._lt.length)return this._ltIndexCache.push(i),this._token.type}return u=this._getToken(),u.type>-1&&!t[u.type].hide&&(u.channel=t[u.type].channel,this._token=u,this._lt.push(u),this._ltIndexCache.push(this._lt.length-this._ltIndex+i),this._lt.length>5&&this._lt.shift(),this._ltIndexCache.length>5&&this._ltIndexCache.shift(),this._ltIndex=this._lt.length),a=t[u.type],a&&(a.hide||a.channel!==undefined&&e!==a.channel)?this.get(e):u.type},LA:function(e){var t=e,n;if(e>0){if(e>5)throw new Error("Too much lookahead.");while(t)n=this.get(),t--;while(t<e)this.unget(),t++}else if(e<0){if(!this._lt[this._ltIndex+e])throw new Error("Too much lookbehind.");n=this._lt[this._ltIndex+e].type}else n=this._token.type;return n},LT:function(e){return this.LA(e),this._lt[this._ltIndex+e-1]},peek:function(){return this.LA(1)},token:function(){return this._token},tokenName:function(e){return e<0||e>this._tokenData.length?"UNKNOWN_TOKEN":this._tokenData[e].name},tokenType:function(e){return this._tokenData[e]||-1},unget:function(){if(!this._ltIndexCache.length)throw new Error("Too much lookahead.");this._ltIndex-=this._ltIndexCache.pop(),this._token=this._lt[this._ltIndex-1]}},parserlib.util={StringReader:t,SyntaxError:n,SyntaxUnit:r,EventTarget:e,TokenStreamBase:i}})(),function(){function Combinator(e,t,n){SyntaxUnit.call(this,e,t,n,Parser.COMBINATOR_TYPE),this.type="unknown",/^\s+$/.test(e)?this.type="descendant":e==">"?this.type="child":e=="+"?this.type="adjacent-sibling":e=="~"&&(this.type="sibling")}function MediaFeature(e,t){SyntaxUnit.call(this,"("+e+(t!==null?":"+t:"")+")",e.startLine,e.startCol,Parser.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}function MediaQuery(e,t,n,r,i){SyntaxUnit.call(this,(e?e+" ":"")+(t?t+" ":"")+n.join(" and "),r,i,Parser.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=n}function Parser(e){EventTarget.call(this),this.options=e||{},this._tokenStream=null}function PropertyName(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.PROPERTY_NAME_TYPE),this.hack=t}function PropertyValue(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n,Parser.PROPERTY_VALUE_TYPE),this.parts=e}function PropertyValueIterator(e){this._i=0,this._parts=e.parts,this._marks=[],this.value=e}function PropertyValuePart(text,line,col){SyntaxUnit.call(this,text,line,col,Parser.PROPERTY_VALUE_PART_TYPE),this.type="unknown";var temp;if(/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)){this.type="dimension",this.value=+RegExp.$1,this.units=RegExp.$2;switch(this.units.toLowerCase()){case"em":case"rem":case"ex":case"px":case"cm":case"mm":case"in":case"pt":case"pc":case"ch":this.type="length";break;case"deg":case"rad":case"grad":this.type="angle";break;case"ms":case"s":this.type="time";break;case"hz":case"khz":this.type="frequency";break;case"dpi":case"dpcm":this.type="resolution"}}else/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp.$1):/^([+\-]?\d+)$/i.test(text)?(this.type="integer",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)$/i.test(text)?(this.type="number",this.value=+RegExp.$1):/^#([a-f0-9]{3,6})/i.test(text)?(this.type="color",temp=RegExp.$1,temp.length==3?(this.red=parseInt(temp.charAt(0)+temp.charAt(0),16),this.green=parseInt(temp.charAt(1)+temp.charAt(1),16),this.blue=parseInt(temp.charAt(2)+temp.charAt(2),16)):(this.red=parseInt(temp.substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring(4,6),16))):/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3):/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100):/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3,this.alpha=+RegExp.$4):/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100,this.alpha=+RegExp.$4):/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100,this.lightness=+RegExp.$3/100):/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100,this.lightness=+RegExp.$3/100,this.alpha=+RegExp.$4):/^url\(["']?([^\)"']+)["']?\)/i.test(text)?(this.type="uri",this.uri=RegExp.$1):/^([^\(]+)\(/i.test(text)?(this.type="function",this.name=RegExp.$1,this.value=text):/^["'][^"']*["']/.test(text)?(this.type="string",this.value=eval(text)):Colors[text.toLowerCase()]?(this.type="color",temp=Colors[text.toLowerCase()].substring(1),this.red=parseInt(temp.substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring(4,6),16)):/^[\,\/]$/.test(text)?(this.type="operator",this.value=text):/^[a-z\-\u0080-\uFFFF][a-z0-9\-\u0080-\uFFFF]*$/i.test(text)&&(this.type="identifier",this.value=text)}function Selector(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n,Parser.SELECTOR_TYPE),this.parts=e,this.specificity=Specificity.calculate(this)}function SelectorPart(e,t,n,r,i){SyntaxUnit.call(this,n,r,i,Parser.SELECTOR_PART_TYPE),this.elementName=e,this.modifiers=t}function SelectorSubPart(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.SELECTOR_SUB_PART_TYPE),this.type=t,this.args=[]}function Specificity(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function isHexDigit(e){return e!==null&&h.test(e)}function isDigit(e){return e!==null&&/\d/.test(e)}function isWhitespace(e){return e!==null&&/\s/.test(e)}function isNewLine(e){return e!==null&&nl.test(e)}function isNameStart(e){return e!==null&&/[a-z_\u0080-\uFFFF\\]/i.test(e)}function isNameChar(e){return e!==null&&(isNameStart(e)||/[0-9\-\\]/.test(e))}function isIdentStart(e){return e!==null&&(isNameStart(e)||/\-\\/.test(e))}function mix(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function TokenStream(e){TokenStreamBase.call(this,e,Tokens)}function ValidationError(e,t,n){this.col=n,this.line=t,this.message=e}var EventTarget=parserlib.util.EventTarget,TokenStreamBase=parserlib.util.TokenStreamBase,StringReader=parserlib.util.StringReader,SyntaxError=parserlib.util.SyntaxError,SyntaxUnit=parserlib.util.SyntaxUnit,Colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};Combinator.prototype=new SyntaxUnit,Combinator.prototype.constructor=Combinator,MediaFeature.prototype=new SyntaxUnit,MediaFeature.prototype.constructor=MediaFeature,MediaQuery.prototype=new SyntaxUnit,MediaQuery.prototype.constructor=MediaQuery,Parser.DEFAULT_TYPE=0,Parser.COMBINATOR_TYPE=1,Parser.MEDIA_FEATURE_TYPE=2,Parser.MEDIA_QUERY_TYPE=3,Parser.PROPERTY_NAME_TYPE=4,Parser.PROPERTY_VALUE_TYPE=5,Parser.PROPERTY_VALUE_PART_TYPE=6,Parser.SELECTOR_TYPE=7,Parser.SELECTOR_PART_TYPE=8,Parser.SELECTOR_SUB_PART_TYPE=9,Parser.prototype=function(){var e=new EventTarget,t,n={constructor:Parser,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e=this._tokenStream,t=null,n,r,i;this.fire("startstylesheet"),this._charset(),this._skipCruft();while(e.peek()==Tokens.IMPORT_SYM)this._import(),this._skipCruft();while(e.peek()==Tokens.NAMESPACE_SYM)this._namespace(),this._skipCruft();i=e.peek();while(i>Tokens.EOF){try{switch(i){case Tokens.MEDIA_SYM:this._media(),this._skipCruft();break;case Tokens.PAGE_SYM:this._page(),this._skipCruft();break;case Tokens.FONT_FACE_SYM:this._font_face(),this._skipCruft();break;case Tokens.KEYFRAMES_SYM:this._keyframes(),this._skipCruft();break;case Tokens.UNKNOWN_SYM:e.get();if(!!this.options.strict)throw new SyntaxError("Unknown @ rule.",e.LT(0).startLine,e.LT(0).startCol);this.fire({type:"error",error:null,message:"Unknown @ rule: "+e.LT(0).value+".",line:e.LT(0).startLine,col:e.LT(0).startCol}),n=0;while(e.advance([Tokens.LBRACE,Tokens.RBRACE])==Tokens.LBRACE)n++;while(n)e.advance([Tokens.RBRACE]),n--;break;case Tokens.S:this._readWhitespace();break;default:if(!this._ruleset())switch(i){case Tokens.CHARSET_SYM:throw r=e.LT(1),this._charset(!1),new SyntaxError("@charset not allowed here.",r.startLine,r.startCol);case Tokens.IMPORT_SYM:throw r=e.LT(1),this._import(!1),new SyntaxError("@import not allowed here.",r.startLine,r.startCol);case Tokens.NAMESPACE_SYM:throw r=e.LT(1),this._namespace(!1),new SyntaxError("@namespace not allowed here.",r.startLine,r.startCol);default:e.get(),this._unexpectedToken(e.token())}}}catch(s){if(!(s instanceof SyntaxError&&!this.options.strict))throw s;this.fire({type:"error",error:s,message:s.message,line:s.line,col:s.col})}i=e.peek()}i!=Tokens.EOF&&this._unexpectedToken(e.token()),this.fire("endstylesheet")},_charset:function(e){var t=this._tokenStream,n,r,i,s;t.match(Tokens.CHARSET_SYM)&&(i=t.token().startLine,s=t.token().startCol,this._readWhitespace(),t.mustMatch(Tokens.STRING),r=t.token(),n=r.value,this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),e!==!1&&this.fire({type:"charset",charset:n,line:i,col:s}))},_import:function(e){var t=this._tokenStream,n,r,i,s=[];t.mustMatch(Tokens.IMPORT_SYM),i=t.token(),this._readWhitespace(),t.mustMatch([Tokens.STRING,Tokens.URI]),r=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this._readWhitespace(),s=this._media_query_list(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace(),e!==!1&&this.fire({type:"import",uri:r,media:s,line:i.startLine,col:i.startCol})},_namespace:function(e){var t=this._tokenStream,n,r,i,s;t.mustMatch(Tokens.NAMESPACE_SYM),n=t.token().startLine,r=t.token().startCol,this._readWhitespace(),t.match(Tokens.IDENT)&&(i=t.token().value,this._readWhitespace()),t.mustMatch([Tokens.STRING,Tokens.URI]),s=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace(),e!==!1&&this.fire({type:"namespace",prefix:i,uri:s,line:n,col:r})},_media:function(){var e=this._tokenStream,t,n,r;e.mustMatch(Tokens.MEDIA_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),r=this._media_query_list(),e.mustMatch(Tokens.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line:t,col:n});for(;;)if(e.peek()==Tokens.PAGE_SYM)this._page();else if(!this._ruleset())break;e.mustMatch(Tokens.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:t,col:n})},_media_query_list:function(){var e=this._tokenStream,t=[];this._readWhitespace(),(e.peek()==Tokens.IDENT||e.peek()==Tokens.LPAREN)&&t.push(this._media_query());while(e.match(Tokens.COMMA))this._readWhitespace(),t.push(this._media_query());return t},_media_query:function(){var e=this._tokenStream,t=null,n=null,r=null,i=[];e.match(Tokens.IDENT)&&(n=e.token().value.toLowerCase(),n!="only"&&n!="not"?(e.unget(),n=null):r=e.token()),this._readWhitespace(),e.peek()==Tokens.IDENT?(t=this._media_type(),r===null&&(r=e.token())):e.peek()==Tokens.LPAREN&&(r===null&&(r=e.LT(1)),i.push(this._media_expression()));if(t===null&&i.length===0)return null;this._readWhitespace();while(e.match(Tokens.IDENT))e.token().value.toLowerCase()!="and"&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression());return new MediaQuery(n,t,i,r.startLine,r.startCol)},_media_type:function(){return this._media_feature()},_media_expression:function(){var e=this._tokenStream,t=null,n,r=null;return e.mustMatch(Tokens.LPAREN),t=this._media_feature(),this._readWhitespace(),e.match(Tokens.COLON)&&(this._readWhitespace(),n=e.LT(1),r=this._expression()),e.mustMatch(Tokens.RPAREN),this._readWhitespace(),new MediaFeature(t,r?new SyntaxUnit(r,n.startLine,n.startCol):null)},_media_feature:function(){var e=this._tokenStream;return e.mustMatch(Tokens.IDENT),SyntaxUnit.fromToken(e.token())},_page:function(){var e=this._tokenStream,t,n,r=null,i=null;e.mustMatch(Tokens.PAGE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),e.match(Tokens.IDENT)&&(r=e.token().value,r.toLowerCase()==="auto"&&this._unexpectedToken(e.token())),e.peek()==Tokens.COLON&&(i=this._pseudo_page()),this._readWhitespace(),this.fire({type:"startpage",id:r,pseudo:i,line:t,col:n}),this._readDeclarations(!0,!0),this.fire({type:"endpage",id:r,pseudo:i,line:t,col:n})},_margin:function(){var e=this._tokenStream,t,n,r=this._margin_sym();return r?(t=e.token().startLine,n=e.token().startCol,this.fire({type:"startpagemargin",margin:r,line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:r,line:t,col:n}),!0):!1},_margin_sym:function(){var e=this._tokenStream;return e.match([Tokens.TOPLEFTCORNER_SYM,Tokens.TOPLEFT_SYM,Tokens.TOPCENTER_SYM,Tokens.TOPRIGHT_SYM,Tokens.TOPRIGHTCORNER_SYM,Tokens.BOTTOMLEFTCORNER_SYM,Tokens.BOTTOMLEFT_SYM,Tokens.BOTTOMCENTER_SYM,Tokens.BOTTOMRIGHT_SYM,Tokens.BOTTOMRIGHTCORNER_SYM,Tokens.LEFTTOP_SYM,Tokens.LEFTMIDDLE_SYM,Tokens.LEFTBOTTOM_SYM,Tokens.RIGHTTOP_SYM,Tokens.RIGHTMIDDLE_SYM,Tokens.RIGHTBOTTOM_SYM])?SyntaxUnit.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream;return e.mustMatch(Tokens.COLON),e.mustMatch(Tokens.IDENT),e.token().value},_font_face:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.FONT_FACE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startfontface",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endfontface",line:t,col:n})},_operator:function(){var e=this._tokenStream,t=null;return e.match([Tokens.SLASH,Tokens.COMMA])&&(t=e.token(),this._readWhitespace()),t?PropertyValuePart.fromToken(t):null},_combinator:function(){var e=this._tokenStream,t=null,n;return e.match([Tokens.PLUS,Tokens.GREATER,Tokens.TILDE])&&(n=e.token(),t=new Combinator(n.value,n.startLine,n.startCol),this._readWhitespace()),t},_unary_operator:function(){var e=this._tokenStream;return e.match([Tokens.MINUS,Tokens.PLUS])?e.token().value:null},_property:function(){var e=this._tokenStream,t=null,n=null,r,i,s,o;return e.peek()==Tokens.STAR&&this.options.starHack&&(e.get(),i=e.token(),n=i.value,s=i.startLine,o=i.startCol),e.match(Tokens.IDENT)&&(i=e.token(),r=i.value,r.charAt(0)=="_"&&this.options.underscoreHack&&(n="_",r=r.substring(1)),t=new PropertyName(r,n,s||i.startLine,o||i.startCol),this._readWhitespace()),t},_ruleset:function(){var e=this._tokenStream,t,n;try{n=this._selectors_group()}catch(r){if(r instanceof SyntaxError&&!this.options.strict){this.fire({type:"error",error:r,message:r.message,line:r.line,col:r.col}),t=e.advance([Tokens.RBRACE]);if(t!=Tokens.RBRACE)throw r;return!0}throw r}return n&&(this.fire({type:"startrule",selectors:n,line:n[0].line,col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endrule",selectors:n,line:n[0].line,col:n[0].col})),n},_selectors_group:function(){var e=this._tokenStream,t=[],n;n=this._selector();if(n!==null){t.push(n);while(e.match(Tokens.COMMA))this._readWhitespace(),n=this._selector(),n!==null?t.push(n):this._unexpectedToken(e.LT(1))}return t.length?t:null},_selector:function(){var e=this._tokenStream,t=[],n=null,r=null,i=null;n=this._simple_selector_sequence();if(n===null)return null;t.push(n);do{r=this._combinator();if(r!==null)t.push(r),n=this._simple_selector_sequence(),n===null?this._unexpectedToken(e.LT(1)):t.push(n);else{if(!this._readWhitespace())break;i=new Combinator(e.token().value,e.token().startLine,e.token().startCol),r=this._combinator(),n=this._simple_selector_sequence(),n===null?r!==null&&this._unexpectedToken(e.LT(1)):(r!==null?t.push(r):t.push(i),t.push(n))}}while(!0);return new Selector(t,t[0].line,t[0].col)},_simple_selector_sequence:function(){var e=this._tokenStream,t=null,n=[],r="",i=[function(){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,o=i.length,u=null,a=!1,f,l;f=e.LT(1).startLine,l=e.LT(1).startCol,t=this._type_selector(),t||(t=this._universal()),t!==null&&(r+=t);for(;;){if(e.peek()===Tokens.S)break;while(s<o&&u===null)u=i[s++].call(this);if(u===null){if(r==="")return null;break}s=0,n.push(u),r+=u.toString(),u=null}return r!==""?new SelectorPart(t,n,r,f,l):null},_type_selector:function(){var e=this._tokenStream,t=this._namespace_prefix(),n=this._element_name();return n?(t&&(n.text=t+n.text,n.col-=t.length),n):(t&&(e.unget(),t.length>1&&e.unget()),null)},_class:function(){var e=this._tokenStream,t;return e.match(Tokens.DOT)?(e.mustMatch(Tokens.IDENT),t=e.token(),new SelectorSubPart("."+t.value,"class",t.startLine,t.startCol-1)):null},_element_name:function(){var e=this._tokenStream,t;return e.match(Tokens.IDENT)?(t=e.token(),new SelectorSubPart(t.value,"elementName",t.startLine,t.startCol)):null},_namespace_prefix:function(){var e=this._tokenStream,t="";if(e.LA(1)===Tokens.PIPE||e.LA(2)===Tokens.PIPE)e.match([Tokens.IDENT,Tokens.STAR])&&(t+=e.token().value),e.mustMatch(Tokens.PIPE),t+="|";return t.length?t:null},_universal:function(){var e=this._tokenStream,t="",n;return n=this._namespace_prefix(),n&&(t+=n),e.match(Tokens.STAR)&&(t+="*"),t.length?t:null},_attrib:function(){var e=this._tokenStream,t=null,n,r;return e.match(Tokens.LBRACKET)?(r=e.token(),t=r.value,t+=this._readWhitespace(),n=this._namespace_prefix(),n&&(t+=n),e.mustMatch(Tokens.IDENT),t+=e.token().value,t+=this._readWhitespace(),e.match([Tokens.PREFIXMATCH,Tokens.SUFFIXMATCH,Tokens.SUBSTRINGMATCH,Tokens.EQUALS,Tokens.INCLUDES,Tokens.DASHMATCH])&&(t+=e.token().value,t+=this._readWhitespace(),e.mustMatch([Tokens.IDENT,Tokens.STRING]),t+=e.token().value,t+=this._readWhitespace()),e.mustMatch(Tokens.RBRACKET),new SelectorSubPart(t+"]","attribute",r.startLine,r.startCol)):null},_pseudo:function(){var e=this._tokenStream,t=null,n=":",r,i;return e.match(Tokens.COLON)&&(e.match(Tokens.COLON)&&(n+=":"),e.match(Tokens.IDENT)?(t=e.token().value,r=e.token().startLine,i=e.token().startCol-n.length):e.peek()==Tokens.FUNCTION&&(r=e.LT(1).startLine,i=e.LT(1).startCol-n.length,t=this._functional_pseudo()),t&&(t=new SelectorSubPart(n+t,"pseudo",r,i))),t},_functional_pseudo:function(){var e=this._tokenStream,t=null;return e.match(Tokens.FUNCTION)&&(t=e.token().value,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(Tokens.RPAREN),t+=")"),t},_expression:function(){var e=this._tokenStream,t="";while(e.match([Tokens.PLUS,Tokens.MINUS,Tokens.DIMENSION,Tokens.NUMBER,Tokens.STRING,Tokens.IDENT,Tokens.LENGTH,Tokens.FREQ,Tokens.ANGLE,Tokens.TIME,Tokens.RESOLUTION]))t+=e.token().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){var e=this._tokenStream,t,n,r="",i,s=null;return e.match(Tokens.NOT)&&(r=e.token().value,t=e.token().startLine,n=e.token().startCol,r+=this._readWhitespace(),i=this._negation_arg(),r+=i,r+=this._readWhitespace(),e.match(Tokens.RPAREN),r+=e.token().value,s=new SelectorSubPart(r,"not",t,n),s.args.push(i)),s},_negation_arg:function(){var e=this._tokenStream,t=[this._type_selector,this._universal,function(){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo],n=null,r=0,i=t.length,s,o,u,a;o=e.LT(1).startLine,u=e.LT(1).startCol;while(r<i&&n===null)n=t[r].call(this),r++;return n===null&&this._unexpectedToken(e.LT(1)),n.type=="elementName"?a=new SelectorPart(n,[],n.toString(),o,u):a=new SelectorPart(null,[n],n.toString(),o,u),a},_declaration:function(){var e=this._tokenStream,t=null,n=null,r=null,i=null,s=null,o="";t=this._property();if(t!==null){e.mustMatch(Tokens.COLON),this._readWhitespace(),n=this._expr(),(!n||n.length===0)&&this._unexpectedToken(e.LT(1)),r=this._prio(),o=t.toString();if(this.options.starHack&&t.hack=="*"||this.options.underscoreHack&&t.hack=="_")o=t.text;try{this._validateProperty(o,n)}catch(u){s=u}return this.fire({type:"property",property:t,value:n,important:r,line:t.line,col:t.col,invalid:s}),!0}return!1},_prio:function(){var e=this._tokenStream,t=e.match(Tokens.IMPORTANT_SYM);return this._readWhitespace(),t},_expr:function(){var e=this._tokenStream,t=[],n=null,r=null;n=this._term();if(n!==null){t.push(n);do{r=this._operator(),r&&t.push(r),n=this._term();if(n===null)break;t.push(n)}while(!0)}return t.length>0?new PropertyValue(t,t[0].line,t[0].col):null},_term:function(){var e=this._tokenStream,t=null,n=null,r,i,s;return t=this._unary_operator(),t!==null&&(i=e.token().startLine,s=e.token().startCol),e.peek()==Tokens.IE_FUNCTION&&this.options.ieFilters?(n=this._ie_function(),t===null&&(i=e.token().startLine,s=e.token().startCol)):e.match([Tokens.NUMBER,Tokens.PERCENTAGE,Tokens.LENGTH,Tokens.ANGLE,Tokens.TIME,Tokens.FREQ,Tokens.STRING,Tokens.IDENT,Tokens.URI,Tokens.UNICODE_RANGE])?(n=e.token().value,t===null&&(i=e.token().startLine,s=e.token().startCol),this._readWhitespace()):(r=this._hexcolor(),r===null?(t===null&&(i=e.LT(1).startLine,s=e.LT(1).startCol),n===null&&(e.LA(3)==Tokens.EQUALS&&this.options.ieFilters?n=this._ie_function():n=this._function())):(n=r.value,t===null&&(i=r.startLine,s=r.startCol))),n!==null?new PropertyValuePart(t!==null?t+n:n,i,s):null},_function:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match(Tokens.FUNCTION)){t=e.token().value,this._readWhitespace(),n=this._expr(),t+=n;if(this.options.ieFilters&&e.peek()==Tokens.EQUALS)do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_ie_function:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match([Tokens.IE_FUNCTION,Tokens.FUNCTION])){t=e.token().value;do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_hexcolor:function(){var e=this._tokenStream,t=null,n;if(e.match(Tokens.HASH)){t=e.token(),n=t.value;if(!/#[a-f0-9]{3,6}/i.test(n))throw new SyntaxError("Expected a hex color but found '"+n+"' at line "+t.startLine+", col "+t.startCol+".",t.startLine,t.startCol);this._readWhitespace()}return t},_keyframes:function(){var e=this._tokenStream,t,n,r,i="";e.mustMatch(Tokens.KEYFRAMES_SYM),t=e.token(),/^@\-([^\-]+)\-/.test(t.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name(),this._readWhitespace(),e.mustMatch(Tokens.LBRACE),this.fire({type:"startkeyframes",name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),n=e.peek();while(n==Tokens.IDENT||n==Tokens.PERCENTAGE)this._keyframe_rule(),this._readWhitespace(),n=e.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),e.mustMatch(Tokens.RBRACE)},_keyframe_name:function(){var e=this._tokenStream,t;return e.mustMatch([Tokens.IDENT,Tokens.STRING]),SyntaxUnit.fromToken(e.token())},_keyframe_rule:function(){var e=this._tokenStream,t,n=this._key_list();this.fire({type:"startkeyframerule",keys:n,line:n[0].line,col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys:n,line:n[0].line,col:n[0].col})},_key_list:function(){var e=this._tokenStream,t,n,r=[];r.push(this._key()),this._readWhitespace();while(e.match(Tokens.COMMA))this._readWhitespace(),r.push(this._key()),this._readWhitespace();return r},_key:function(){var e=this._tokenStream,t;if(e.match(Tokens.PERCENTAGE))return SyntaxUnit.fromToken(e.token());if(e.match(Tokens.IDENT)){t=e.token();if(/from|to/i.test(t.value))return SyntaxUnit.fromToken(t);e.unget()}this._unexpectedToken(e.LT(1))},_skipCruft:function(){while(this._tokenStream.match([Tokens.S,Tokens.CDO,Tokens.CDC]));},_readDeclarations:function(e,t){var n=this._tokenStream,r;this._readWhitespace(),e&&n.mustMatch(Tokens.LBRACE),this._readWhitespace();try{for(;;){if(!(n.match(Tokens.SEMICOLON)||t&&this._margin())){if(!this._declaration())break;if(!n.match(Tokens.SEMICOLON))break}this._readWhitespace()}n.mustMatch(Tokens.RBRACE),this._readWhitespace()}catch(i){if(!(i instanceof SyntaxError&&!this.options.strict))throw i;this.fire({type:"error",error:i,message:i.message,line:i.line,col:i.col}),r=n.advance([Tokens.SEMICOLON,Tokens.RBRACE]);if(r==Tokens.SEMICOLON)this._readDeclarations(!1,t);else if(r!=Tokens.RBRACE)throw i}},_readWhitespace:function(){var e=this._tokenStream,t="";while(e.match(Tokens.S))t+=e.token().value;return t},_unexpectedToken:function(e){throw new SyntaxError("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!=Tokens.EOF&&this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){Validation.validate(e,t)},parse:function(e){this._tokenStream=new TokenStream(e,Tokens),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery:function(e){this._tokenStream=new TokenStream(e,Tokens);var t=this._media_query();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._expr();return this._readWhitespace(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._ruleset();return this._readWhitespace(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._selector();return this._readWhitespace(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new TokenStream(e,Tokens),this._readDeclarations()}};for(t in n)n.hasOwnProperty(t)&&(e[t]=n[t]);return e}();var Properties={"alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | <percentage> | <length>","alignment-baseline":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",animation:1,"animation-delay":{multi:"<time>",comma:!0},"animation-direction":{multi:"normal | alternate",comma:!0},"animation-duration":{multi:"<time>",comma:!0},"animation-iteration-count":{multi:"<number> | infinite",comma:!0},"animation-name":{multi:"none | <ident>",comma:!0},"animation-play-state":{multi:"running | paused",comma:!0},"animation-timing-function":1,"-moz-animation-delay":{multi:"<time>",comma:!0},"-moz-animation-direction":{multi:"normal | alternate",comma:!0},"-moz-animation-duration":{multi:"<time>",comma:!0},"-moz-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-moz-animation-name":{multi:"none | <ident>",comma:!0},"-moz-animation-play-state":{multi:"running | paused",comma:!0},"-ms-animation-delay":{multi:"<time>",comma:!0},"-ms-animation-direction":{multi:"normal | alternate",comma:!0},"-ms-animation-duration":{multi:"<time>",comma:!0},"-ms-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-ms-animation-name":{multi:"none | <ident>",comma:!0},"-ms-animation-play-state":{multi:"running | paused",comma:!0},"-webkit-animation-delay":{multi:"<time>",comma:!0},"-webkit-animation-direction":{multi:"normal | alternate",comma:!0},"-webkit-animation-duration":{multi:"<time>",comma:!0},"-webkit-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-webkit-animation-name":{multi:"none | <ident>",comma:!0},"-webkit-animation-play-state":{multi:"running | paused",comma:!0},"-o-animation-delay":{multi:"<time>",comma:!0},"-o-animation-direction":{multi:"normal | alternate",comma:!0},"-o-animation-duration":{multi:"<time>",comma:!0},"-o-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-o-animation-name":{multi:"none | <ident>",comma:!0},"-o-animation-play-state":{multi:"running | paused",comma:!0},appearance:"icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | inherit",azimuth:function(e){var t="<angle> | leftwards | rightwards | inherit",n="left-side | far-left | left | center-left | center | center-right | right | far-right | right-side",r=!1,i=!1,s;ValidationTypes.isAny(e,t)||(ValidationTypes.isAny(e,"behind")&&(r=!0,i=!0),ValidationTypes.isAny(e,n)&&(i=!0,r||ValidationTypes.isAny(e,"behind")));if(e.hasNext())throw s=e.next(),i?new ValidationError("Expected end of value but found '"+s+"'.",s.line,s.col):new ValidationError("Expected (<'azimuth'>) but found '"+s+"'.",s.line,s.col)},"backface-visibility":"visible | hidden",background:1,"background-attachment":{multi:"<attachment>",comma:!0},"background-clip":{multi:"<box>",comma:!0},"background-color":"<color> | inherit","background-image":{multi:"<bg-image>",comma:!0},"background-origin":{multi:"<box>",comma:!0},"background-position":{multi:"<bg-position>",comma:!0},"background-repeat":{multi:"<repeat-style>"},"background-size":{multi:"<bg-size>",comma:!0},"baseline-shift":"baseline | sub | super | <percentage> | <length>",behavior:1,binding:1,bleed:"<length>","bookmark-label":"<content> | <attr> | <string>","bookmark-level":"none | <integer>","bookmark-state":"open | closed","bookmark-target":"none | <uri> | <attr>",border:"<border-width> || <border-style> || <color>","border-bottom":"<border-width> || <border-style> || <color>","border-bottom-color":"<color>","border-bottom-left-radius":"<x-one-radius>","border-bottom-right-radius":"<x-one-radius>","border-bottom-style":"<border-style>","border-bottom-width":"<border-width>","border-collapse":"collapse | separate | inherit","border-color":{multi:"<color> | inherit",max:4},"border-image":1,"border-image-outset":{multi:"<length> | <number>",max:4},"border-image-repeat":{multi:"stretch | repeat | round",max:2},"border-image-slice":function(e){var t=!1,n="<number> | <percentage>",r=!1,i=0,s=4,o;ValidationTypes.isAny(e,"fill")&&(r=!0,t=!0);while(e.hasNext()&&i<s){t=ValidationTypes.isAny(e,n);if(!t)break;i++}r?t=!0:ValidationTypes.isAny(e,"fill");if(e.hasNext())throw o=e.next(),t?new ValidationError("Expected end of value but found '"+o+"'.",o.line,o.col):new ValidationError("Expected ([<number> | <percentage>]{1,4} && fill?) but found '"+o+"'.",o.line,o.col)},"border-image-source":"<image> | none","border-image-width":{multi:"<length> | <percentage> | <number> | auto",max:4},"border-left":"<border-width> || <border-style> || <color>","border-left-color":"<color> | inherit","border-left-style":"<border-style>","border-left-width":"<border-width>","border-radius":function(e){var t=!1,n="<length> | <percentage>",r=!1,i=!1,s=0,o=8,u;while(e.hasNext()&&s<o){t=ValidationTypes.isAny(e,n);if(!t){if(!(e.peek()=="/"&&s>1&&!r))break;r=!0,o=s+5,e.next()}s++}if(e.hasNext())throw u=e.next(),t?new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col):new ValidationError("Expected (<'border-radius'>) but found '"+u+"'.",u.line,u.col)},"border-right":"<border-width> || <border-style> || <color>","border-right-color":"<color> | inherit","border-right-style":"<border-style>","border-right-width":"<border-width>","border-spacing":{multi:"<length> | inherit",max:2},"border-style":{multi:"<border-style>",max:4},"border-top":"<border-width> || <border-style> || <color>","border-top-color":"<color> | inherit","border-top-left-radius":"<x-one-radius>","border-top-right-radius":"<x-one-radius>","border-top-style":"<border-style>","border-top-width":"<border-width>","border-width":{multi:"<border-width>",max:4},bottom:"<margin-width> | inherit","box-align":"start | end | center | baseline | stretch","box-decoration-break":"slice |clone","box-direction":"normal | reverse | inherit","box-flex":"<number>","box-flex-group":"<integer>","box-lines":"single | multiple","box-ordinal-group":"<integer>","box-orient":"horizontal | vertical | inline-axis | block-axis | inherit","box-pack":"start | end | center | justify","box-shadow":function(e){var t=!1,n;if(!ValidationTypes.isAny(e,"none"))Validation.multiProperty("<shadow>",e,!0,Infinity);else if(e.hasNext())throw n=e.next(),new ValidationError("Expected end of value but found '"+n+"'.",n.line,n.col)},"box-sizing":"content-box | border-box | inherit","break-after":"auto | always | avoid | left | right | page | column | avoid-page | avoid-column","break-before":"auto | always | avoid | left | right | page | column | avoid-page | avoid-column","break-inside":"auto | avoid | avoid-page | avoid-column","caption-side":"top | bottom | inherit",clear:"none | right | left | both | inherit",clip:1,color:"<color> | inherit","color-profile":1,"column-count":"<integer> | auto","column-fill":"auto | balance","column-gap":"<length> | normal","column-rule":"<border-width> || <border-style> || <color>","column-rule-color":"<color>","column-rule-style":"<border-style>","column-rule-width":"<border-width>","column-span":"none | all","column-width":"<length> | auto",columns:1,content:1,"counter-increment":1,"counter-reset":1,crop:"<shape> | auto",cue:"cue-after | cue-before | inherit","cue-after":1,"cue-before":1,cursor:1,direction:"ltr | rtl | inherit",display:"inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | box | inline-box | grid | inline-grid | none | inherit","dominant-baseline":1,"drop-initial-after-adjust":"central | middle | after-edge | text-after-edge | ideographic | alphabetic | mathematical | <percentage> | <length>","drop-initial-after-align":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical","drop-initial-before-adjust":"before-edge | text-before-edge | central | middle | hanging | mathematical | <percentage> | <length>","drop-initial-before-align":"caps-height | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical","drop-initial-size":"auto | line | <length> | <percentage>","drop-initial-value":"initial | <integer>",elevation:"<angle> | below | level | above | higher | lower | inherit","empty-cells":"show | hide | inherit",filter:1,fit:"fill | hidden | meet | slice","fit-position":1,"float":"left | right | none | inherit","float-offset":1,font:1,"font-family":1,"font-size":"<absolute-size> | <relative-size> | <length> | <percentage> | inherit","font-size-adjust":"<number> | none | inherit","font-stretch":"normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | inherit","font-style":"normal | italic | oblique | inherit","font-variant":"normal | small-caps | inherit","font-weight":"normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit","grid-cell-stacking":"columns | rows | layer","grid-column":1,"grid-columns":1,"grid-column-align":"start | end | center | stretch","grid-column-sizing":1,"grid-column-span":"<integer>","grid-flow":"none | rows | columns","grid-layer":"<integer>","grid-row":1,"grid-rows":1,"grid-row-align":"start | end | center | stretch","grid-row-span":"<integer>","grid-row-sizing":1,"hanging-punctuation":1,height:"<margin-width> | inherit","hyphenate-after":"<integer> | auto","hyphenate-before":"<integer> | auto","hyphenate-character":"<string> | auto","hyphenate-lines":"no-limit | <integer>","hyphenate-resource":1,hyphens:"none | manual | auto",icon:1,"image-orientation":"angle | auto","image-rendering":1,"image-resolution":1,"inline-box-align":"initial | last | <integer>",left:"<margin-width> | inherit","letter-spacing":"<length> | normal | inherit","line-height":"<number> | <length> | <percentage> | normal | inherit","line-break":"auto | loose | normal | strict","line-stacking":1,"line-stacking-ruby":"exclude-ruby | include-ruby","line-stacking-shift":"consider-shifts | disregard-shifts","line-stacking-strategy":"inline-line-height | block-line-height | max-height | grid-height","list-style":1,"list-style-image":"<uri> | none | inherit","list-style-position":"inside | outside | inherit","list-style-type":"disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none | inherit",margin:{multi:"<margin-width> | inherit",max:4},"margin-bottom":"<margin-width> | inherit","margin-left":"<margin-width> | inherit","margin-right":"<margin-width> | inherit","margin-top":"<margin-width> | inherit",mark:1,"mark-after":1,"mark-before":1,marks:1,"marquee-direction":1,"marquee-play-count":1,"marquee-speed":1,"marquee-style":1,"max-height":"<length> | <percentage> | none | inherit","max-width":"<length> | <percentage> | none | inherit","min-height":"<length> | <percentage> | inherit","min-width":"<length> | <percentage> | inherit","move-to":1,"nav-down":1,"nav-index":1,"nav-left":1,"nav-right":1,"nav-up":1,opacity:"<number> | inherit",orphans:"<integer> | inherit",outline:1,"outline-color":"<color> | invert | inherit","outline-offset":1,"outline-style":"<border-style> | inherit","outline-width":"<border-width> | inherit",overflow:"visible | hidden | scroll | auto | inherit","overflow-style":1,"overflow-x":1,"overflow-y":1,padding:{multi:"<padding-width> | inherit",max:4},"padding-bottom":"<padding-width> | inherit","padding-left":"<padding-width> | inherit","padding-right":"<padding-width> | inherit","padding-top":"<padding-width> | inherit",page:1,"page-break-after":"auto | always | avoid | left | right | inherit","page-break-before":"auto | always | avoid | left | right | inherit","page-break-inside":"auto | avoid | inherit","page-policy":1,pause:1,"pause-after":1,"pause-before":1,perspective:1,"perspective-origin":1,phonemes:1,pitch:1,"pitch-range":1,"play-during":1,"pointer-events":"auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit",position:"static | relative | absolute | fixed | inherit","presentation-level":1,"punctuation-trim":1,quotes:1,"rendering-intent":1,resize:1,rest:1,"rest-after":1,"rest-before":1,richness:1,right:"<margin-width> | inherit",rotation:1,"rotation-point":1,"ruby-align":1,"ruby-overhang":1,"ruby-position":1,"ruby-span":1,size:1,speak:"normal | none | spell-out | inherit","speak-header":"once | always | inherit","speak-numeral":"digits | continuous | inherit","speak-punctuation":"code | none | inherit","speech-rate":1,src:1,stress:1,"string-set":1,"table-layout":"auto | fixed | inherit","tab-size":"<integer> | <length>",target:1,"target-name":1,"target-new":1,"target-position":1,"text-align":"left | right | center | justify | inherit","text-align-last":1,"text-decoration":1,"text-emphasis":1,"text-height":1,"text-indent":"<length> | <percentage> | inherit","text-justify":"auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida","text-outline":1,"text-overflow":1,"text-rendering":"auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit","text-shadow":1,"text-transform":"capitalize | uppercase | lowercase | none | inherit","text-wrap":"normal | none | avoid",top:"<margin-width> | inherit",transform:1,"transform-origin":1,"transform-style":1,transition:1,"transition-delay":1,"transition-duration":1,"transition-property":1,"transition-timing-function":1,"unicode-bidi":"normal | embed | bidi-override | inherit","user-modify":"read-only | read-write | write-only | inherit","user-select":"none | text | toggle | element | elements | all | inherit","vertical-align":"<percentage> | <length> | baseline | sub | super | top | text-top | middle | bottom | text-bottom | inherit",visibility:"visible | hidden | collapse | inherit","voice-balance":1,"voice-duration":1,"voice-family":1,"voice-pitch":1,"voice-pitch-range":1,"voice-rate":1,"voice-stress":1,"voice-volume":1,volume:1,"white-space":"normal | pre | nowrap | pre-wrap | pre-line | inherit","white-space-collapse":1,widows:"<integer> | inherit",width:"<length> | <percentage> | auto | inherit","word-break":"normal | keep-all | break-all","word-spacing":"<length> | normal | inherit","word-wrap":1,"z-index":"<integer> | auto | inherit",zoom:"<number> | <percentage> | normal"};PropertyName.prototype=new SyntaxUnit,PropertyName.prototype.constructor=PropertyName,PropertyName.prototype.toString=function(){return(this.hack?this.hack:"")+this.text},PropertyValue.prototype=new SyntaxUnit,PropertyValue.prototype.constructor=PropertyValue,PropertyValueIterator.prototype.count=function(){return this._parts.length},PropertyValueIterator.prototype.isFirst=function(){return this._i===0},PropertyValueIterator.prototype.hasNext=function(){return this._i<this._parts.length},PropertyValueIterator.prototype.mark=function(){this._marks.push(this._i)},PropertyValueIterator.prototype.peek=function(e){return this.hasNext()?this._parts[this._i+(e||0)]:null},PropertyValueIterator.prototype.next=function(){return this.hasNext()?this._parts[this._i++]:null},PropertyValueIterator.prototype.previous=function(){return this._i>0?this._parts[--this._i]:null},PropertyValueIterator.prototype.restore=function(){this._marks.length&&(this._i=this._marks.pop())},PropertyValuePart.prototype=new SyntaxUnit,PropertyValuePart.prototype.constructor=PropertyValuePart,PropertyValuePart.fromToken=function(e){return new PropertyValuePart(e.value,e.startLine,e.startCol)};var Pseudos={":first-letter":1,":first-line":1,":before":1,":after":1};Pseudos.ELEMENT=1,Pseudos.CLASS=2,Pseudos.isElement=function(e){return e.indexOf("::")===0||Pseudos[e.toLowerCase()]==Pseudos.ELEMENT},Selector.prototype=new SyntaxUnit,Selector.prototype.constructor=Selector,SelectorPart.prototype=new SyntaxUnit,SelectorPart.prototype.constructor=SelectorPart,SelectorSubPart.prototype=new SyntaxUnit,SelectorSubPart.prototype.constructor=SelectorSubPart,Specificity.prototype={constructor:Specificity,compare:function(e){var t=["a","b","c","d"],n,r;for(n=0,r=t.length;n<r;n++){if(this[t[n]]<e[t[n]])return-1;if(this[t[n]]>e[t[n]])return 1}return 0},valueOf:function(){return this.a*1e3+this.b*100+this.c*10+this.d},toString:function(){return this.a+","+this.b+","+this.c+","+this.d}},Specificity.calculate=function(e){function u(e){var t,n,r,a,f=e.elementName?e.elementName.text:"",l;f&&f.charAt(f.length-1)!="*"&&o++;for(t=0,r=e.modifiers.length;t<r;t++){l=e.modifiers[t];switch(l.type){case"class":case"attribute":s++;break;case"id":i++;break;case"pseudo":Pseudos.isElement(l.text)?o++:s++;break;case"not":for(n=0,a=l.args.length;n<a;n++)u(l.args[n])}}}var t,n,r,i=0,s=0,o=0;for(t=0,n=e.parts.length;t<n;t++)r=e.parts[t],r instanceof SelectorPart&&u(r);return new Specificity(0,i,s,o)};var h=/^[0-9a-fA-F]$/,nonascii=/^[\u0080-\uFFFF]$/,nl=/\n|\r\n|\r|\f/;TokenStream.prototype=mix(new TokenStreamBase,{_getToken:function(e){var t,n=this._reader,r=null,i=n.getLine(),s=n.getCol();t=n.read();while(t){switch(t){case"/":n.peek()=="*"?r=this.commentToken(t,i,s):r=this.charToken(t,i,s);break;case"|":case"~":case"^":case"$":case"*":n.peek()=="="?r=this.comparisonToken(t,i,s):r=this.charToken(t,i,s);break;case'"':case"'":r=this.stringToken(t,i,s);break;case"#":isNameChar(n.peek())?r=this.hashToken(t,i,s):r=this.charToken(t,i,s);break;case".":isDigit(n.peek())?r=this.numberToken(t,i,s):r=this.charToken(t,i,s);break;case"-":n.peek()=="-"?r=this.htmlCommentEndToken(t,i,s):isNameStart(n.peek())?r=this.identOrFunctionToken(t,i,s):r=this.charToken(t,i,s);break;case"!":r=this.importantToken(t,i,s);break;case"@":r=this.atRuleToken(t,i,s);break;case":":r=this.notToken(t,i,s);break;case"<":r=this.htmlCommentStartToken(t,i,s);break;case"U":case"u":if(n.peek()=="+"){r=this.unicodeRangeToken(t,i,s);break};default:isDigit(t)?r=this.numberToken(t,i,s):isWhitespace(t)?r=this.whitespaceToken(t,i,s):isIdentStart(t)?r=this.identOrFunctionToken(t,i,s):r=this.charToken(t,i,s)}break}return!r&&t===null&&(r=this.createToken(Tokens.EOF,null,i,s)),r},createToken:function(e,t,n,r,i){var s=this._reader;return i=i||{},{value:t,type:e,channel:i.channel,hide:i.hide||!1,startLine:n,startCol:r,endLine:s.getLine(),endCol:s.getCol()}},atRuleToken:function(e,t,n){var r=e,i=this._reader,s=Tokens.CHAR,o=!1,u,a;i.mark(),u=this.readName(),r=e+u,s=Tokens.type(r.toLowerCase());if(s==Tokens.CHAR||s==Tokens.UNKNOWN)r.length>1?s=Tokens.UNKNOWN_SYM:(s=Tokens.CHAR,r=e,i.reset());return this.createToken(s,r,t,n)},charToken:function(e,t,n){var r=Tokens.type(e);return r==-1&&(r=Tokens.CHAR),this.createToken(r,e,t,n)},commentToken:function(e,t,n){var r=this._reader,i=this.readComment(e);return this.createToken(Tokens.COMMENT,i,t,n)},comparisonToken:function(e,t,n){var r=this._reader,i=e+r.read(),s=Tokens.type(i)||Tokens.CHAR;return this.createToken(s,i,t,n)},hashToken:function(e,t,n){var r=this._reader,i=this.readName(e);return this.createToken(Tokens.HASH,i,t,n)},htmlCommentStartToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(3),i=="<!--"?this.createToken(Tokens.CDO,i,t,n):(r.reset(),this.charToken(e,t,n))},htmlCommentEndToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(2),i=="-->"?this.createToken(Tokens.CDC,i,t,n):(r.reset(),this.charToken(e,t,n))},identOrFunctionToken:function(e,t,n){var r=this._reader,i=this.readName(e),s=Tokens.IDENT;return r.peek()=="("?(i+=r.read(),i.toLowerCase()=="url("?(s=Tokens.URI,i=this.readURI(i),i.toLowerCase()=="url("&&(s=Tokens.FUNCTION)):s=Tokens.FUNCTION):r.peek()==":"&&i.toLowerCase()=="progid"&&(i+=r.readTo("("),s=Tokens.IE_FUNCTION),this.createToken(s,i,t,n)},importantToken:function(e,t,n){var r=this._reader,i=e,s=Tokens.CHAR,o,u;r.mark(),u=r.read();while(u){if(u=="/"){if(r.peek()!="*")break;o=this.readComment(u);if(o==="")break}else{if(!isWhitespace(u)){if(/i/i.test(u)){o=r.readCount(8),/mportant/i.test(o)&&(i+=u+o,s=Tokens.IMPORTANT_SYM);break}break}i+=u+this.readWhitespace()}u=r.read()}return s==Tokens.CHAR?(r.reset(),this.charToken(e,t,n)):this.createToken(s,i,t,n)},notToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(4),i.toLowerCase()==":not("?this.createToken(Tokens.NOT,i,t,n):(r.reset(),this.charToken(e,t,n))},numberToken:function(e,t,n){var r=this._reader,i=this.readNumber(e),s,o=Tokens.NUMBER,u=r.peek();return isIdentStart(u)?(s=this.readName(r.read()),i+=s,/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^vm$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(s)?o=Tokens.LENGTH:/^deg|^rad$|^grad$/i.test(s)?o=Tokens.ANGLE:/^ms$|^s$/i.test(s)?o=Tokens.TIME:/^hz$|^khz$/i.test(s)?o=Tokens.FREQ:/^dpi$|^dpcm$/i.test(s)?o=Tokens.RESOLUTION:o=Tokens.DIMENSION):u=="%"&&(i+=r.read(),o=Tokens.PERCENTAGE),this.createToken(o,i,t,n)},stringToken:function(e,t,n){var r=e,i=e,s=this._reader,o=e,u=Tokens.STRING,a=s.read();while(a){i+=a;if(a==r&&o!="\\")break;if(isNewLine(s.peek())&&a!="\\"){u=Tokens.INVALID;break}o=a,a=s.read()}return a===null&&(u=Tokens.INVALID),this.createToken(u,i,t,n)},unicodeRangeToken:function(e,t,n){var r=this._reader,i=e,s,o=Tokens.CHAR;return r.peek()=="+"&&(r.mark(),i+=r.read(),i+=this.readUnicodeRangePart(!0),i.length==2?r.reset():(o=Tokens.UNICODE_RANGE,i.indexOf("?")==-1&&r.peek()=="-"&&(r.mark(),s=r.read(),s+=this.readUnicodeRangePart(!1),s.length==1?r.reset():i+=s))),this.createToken(o,i,t,n)},whitespaceToken:function(e,t,n){var r=this._reader,i=e+this.readWhitespace();return this.createToken(Tokens.S,i,t,n)},readUnicodeRangePart:function(e){var t=this._reader,n="",r=t.peek();while(isHexDigit(r)&&n.length<6)t.read(),n+=r,r=t.peek();if(e)while(r=="?"&&n.length<6)t.read(),n+=r,r=t.peek();return n},readWhitespace:function(){var e=this._reader,t="",n=e.peek();while(isWhitespace(n))e.read(),t+=n,n=e.peek();return t},readNumber:function(e){var t=this._reader,n=e,r=e==".",i=t.peek();while(i){if(isDigit(i))n+=t.read();else{if(i!=".")break;if(r)break;r=!0,n+=t.read()}i=t.peek()}return n},readString:function(){var e=this._reader,t=e.read(),n=t,r=t,i=e.peek();while(i){i=e.read(),n+=i;if(i==t&&r!="\\")break;if(isNewLine(e.peek())&&i!="\\"){n="";break}r=i,i=e.peek()}return i===null&&(n=""),n},readURI:function(e){var t=this._reader,n=e,r="",i=t.peek();t.mark();while(i&&isWhitespace(i))t.read(),i=t.peek();i=="'"||i=='"'?r=this.readString():r=this.readURL(),i=t.peek();while(i&&isWhitespace(i))t.read(),i=t.peek();return r===""||i!=")"?(n=e,t.reset()):n+=r+t.read(),n},readURL:function(){var e=this._reader,t="",n=e.peek();while(/^[!#$%&\\*-~]$/.test(n))t+=e.read(),n=e.peek();return t},readName:function(e){var t=this._reader,n=e||"",r=t.peek();for(;;)if(r=="\\")n+=this.readEscape(t.read()),r=t.peek();else{if(!r||!isNameChar(r))break;n+=t.read(),r=t.peek()}return n},readEscape:function(e){var t=this._reader,n=e||"",r=0,i=t.peek();if(isHexDigit(i))do n+=t.read(),i=t.peek();while(i&&isHexDigit(i)&&++r<6);return n.length==3&&/\s/.test(i)||n.length==7||n.length==1?t.read():i="",n+i},readComment:function(e){var t=this._reader,n=e||"",r=t.read();if(r=="*"){while(r){n+=r;if(n.length>2&&r=="*"&&t.peek()=="/"){n+=t.read();break}r=t.read()}return n}return""}});var Tokens=[{name:"CDO"},{name:"CDC"},{name:"S",whitespace:!0},{name:"COMMENT",comment:!0,hide:!0,channel:"comment"},{name:"INCLUDES",text:"~="},{name:"DASHMATCH",text:"|="},{name:"PREFIXMATCH",text:"^="},{name:"SUFFIXMATCH",text:"$="},{name:"SUBSTRINGMATCH",text:"*="},{name:"STRING"},{name:"IDENT"},{name:"HASH"},{name:"IMPORT_SYM",text:"@import"},{name:"PAGE_SYM",text:"@page"},{name:"MEDIA_SYM",text:"@media"},{name:"FONT_FACE_SYM",text:"@font-face"},{name:"CHARSET_SYM",text:"@charset"},{name:"NAMESPACE_SYM",text:"@namespace"},{name:"UNKNOWN_SYM"},{name:"KEYFRAMES_SYM",text:["@keyframes","@-webkit-keyframes","@-moz-keyframes","@-o-keyframes"]},{name:"IMPORTANT_SYM"},{name:"LENGTH"},{name:"ANGLE"},{name:"TIME"},{name:"FREQ"},{name:"DIMENSION"},{name:"PERCENTAGE"},{name:"NUMBER"},{name:"URI"},{name:"FUNCTION"},{name:"UNICODE_RANGE"},{name:"INVALID"},{name:"PLUS",text:"+"},{name:"GREATER",text:">"},{name:"COMMA",text:","},{name:"TILDE",text:"~"},{name:"NOT"},{name:"TOPLEFTCORNER_SYM",text:"@top-left-corner"},{name:"TOPLEFT_SYM",text:"@top-left"},{name:"TOPCENTER_SYM",text:"@top-center"},{name:"TOPRIGHT_SYM",text:"@top-right"},{name:"TOPRIGHTCORNER_SYM",text:"@top-right-corner"},{name:"BOTTOMLEFTCORNER_SYM",text:"@bottom-left-corner"},{name:"BOTTOMLEFT_SYM",text:"@bottom-left"},{name:"BOTTOMCENTER_SYM",text:"@bottom-center"},{name:"BOTTOMRIGHT_SYM",text:"@bottom-right"},{name:"BOTTOMRIGHTCORNER_SYM",text:"@bottom-right-corner"},{name:"LEFTTOP_SYM",text:"@left-top"},{name:"LEFTMIDDLE_SYM",text:"@left-middle"},{name:"LEFTBOTTOM_SYM",text:"@left-bottom"},{name:"RIGHTTOP_SYM",text:"@right-top"},{name:"RIGHTMIDDLE_SYM",text:"@right-middle"},{name:"RIGHTBOTTOM_SYM",text:"@right-bottom"},{name:"RESOLUTION",state:"media"},{name:"IE_FUNCTION"},{name:"CHAR"},{name:"PIPE",text:"|"},{name:"SLASH",text:"/"},{name:"MINUS",text:"-"},{name:"STAR",text:"*"},{name:"LBRACE",text:"{"},{name:"RBRACE",text:"}"},{name:"LBRACKET",text:"["},{name:"RBRACKET",text:"]"},{name:"EQUALS",text:"="},{name:"COLON",text:":"},{name:"SEMICOLON",text:";"},{name:"LPAREN",text:"("},{name:"RPAREN",text:")"},{name:"DOT",text:"."}];(function(){var e=[],t={};Tokens.UNKNOWN=-1,Tokens.unshift({name:"EOF"});for(var n=0,r=Tokens.length;n<r;n++){e.push(Tokens[n].name),Tokens[Tokens[n].name]=n;if(Tokens[n].text)if(Tokens[n].text instanceof Array)for(var i=0;i<Tokens[n].text.length;i++)t[Tokens[n].text[i]]=n;else t[Tokens[n].text]=n}Tokens.name=function(t){return e[t]},Tokens.type=function(e){return t[e]||-1}})();var Validation={validate:function(e,t){var n=e.toString().toLowerCase(),r=t.parts,i=new PropertyValueIterator(t),s=Properties[n],o,u,a,f,l,c,h,p,d,v,m;if(!s){if(n.indexOf("-")!==0)throw new ValidationError("Unknown property '"+e+"'.",e.line,e.col)}else typeof s!="number"&&(typeof s=="string"?s.indexOf("||")>-1?this.groupProperty(s,i):this.singleProperty(s,i,1):s.multi?this.multiProperty(s.multi,i,s.comma,s.max||Infinity):typeof s=="function"&&s(i))},singleProperty:function(e,t,n,r){var i=!1,s=t.value,o=0,u;while(t.hasNext()&&o<n){i=ValidationTypes.isAny(t,e);if(!i)break;o++}if(!i)throw t.hasNext()&&!t.isFirst()?(u=t.peek(),new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col)):new ValidationError("Expected ("+e+") but found '"+s+"'.",s.line,s.col);if(t.hasNext())throw u=t.next(),new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col)},multiProperty:function(e,t,n,r){var i=!1,s=t.value,o=0,u=!1,a;while(t.hasNext()&&!i&&o<r){if(!ValidationTypes.isAny(t,e))break;o++;if(!t.hasNext())i=!0;else if(n){if(t.peek()!=",")break;a=t.next()}}if(!i)throw t.hasNext()&&!t.isFirst()?(a=t.peek(),new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col)):(a=t.previous(),n&&a==","?new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col):new ValidationError("Expected ("+e+") but found '"+s+"'.",s.line,s.col));if(t.hasNext())throw a=t.next(),new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col)},groupProperty:function(e,t,n){var r=!1,i=t.value,s=e.split("||").length,o={count:0},u=!1,a,f;while(t.hasNext()&&!r){a=ValidationTypes.isAnyOfGroup(t,e);if(!a)break;if(o[a])break;o[a]=1,o.count++,u=!0;if(o.count==s||!t.hasNext())r=!0}if(!r)throw u&&t.hasNext()?(f=t.peek(),new ValidationError("Expected end of value but found '"+f+"'.",f.line,f.col)):new ValidationError("Expected ("+e+") but found '"+i+"'.",i.line,i.col);if(t.hasNext())throw f=t.next(),new ValidationError("Expected end of value but found '"+f+"'.",f.line,f.col)}};ValidationError.prototype=new Error;var ValidationTypes={isLiteral:function(e,t){var n=e.text.toString().toLowerCase(),r=t.split(" | "),i,s,o=!1;for(i=0,s=r.length;i<s&&!o;i++)n==r[i].toLowerCase()&&(o=!0);return o},isSimple:function(e){return!!this.simple[e]},isComplex:function(e){return!!this.complex[e]},isAny:function(e,t){var n=t.split(" | "),r,i,s=!1;for(r=0,i=n.length;r<i&&!s&&e.hasNext();r++)s=this.isType(e,n[r]);return s},isAnyOfGroup:function(e,t){var n=t.split(" || "),r,i,s=!1;for(r=0,i=n.length;r<i&&!s;r++)s=this.isType(e,n[r]);return s?n[r-1]:!1},isType:function(e,t){var n=e.peek(),r=!1;return t.charAt(0)!="<"?(r=this.isLiteral(n,t),r&&e.next()):this.simple[t]?(r=this.simple[t](n),r&&e.next()):r=this.complex[t](e),r},simple:{"<absolute-size>":function(e){return ValidationTypes.isLiteral(e,"xx-small | x-small | small | medium | large | x-large | xx-large")},"<attachment>":function(e){return ValidationTypes.isLiteral(e,"scroll | fixed | local")},"<attr>":function(e){return e.type=="function"&&e.name=="attr"},"<bg-image>":function(e){return this["<image>"](e)||this["<gradient>"](e)||e=="none"},"<gradient>":function(e){return e.type=="function"&&/^(?:\-(?:ms|moz|o|webkit)\-)?(?:repeating\-)?(?:radial\-|linear\-)?gradient/i.test(e)},"<box>":function(e){return ValidationTypes.isLiteral(e,"padding-box | border-box | content-box")},"<content>":function(e){return e.type=="function"&&e.name=="content"},"<relative-size>":function(e){return ValidationTypes.isLiteral(e,"smaller | larger")},"<ident>":function(e){return e.type=="identifier"},"<length>":function(e){return e.type=="length"||e.type=="number"||e.type=="integer"||e=="0"},"<color>":function(e){return e.type=="color"||e=="transparent"},"<number>":function(e){return e.type=="number"||this["<integer>"](e)},"<integer>":function(e){return e.type=="integer"},"<line>":function(e){return e.type=="integer"},"<angle>":function(e){return e.type=="angle"},"<uri>":function(e){return e.type=="uri"},"<image>":function(e){return this["<uri>"](e)},"<percentage>":function(e){return e.type=="percentage"||e=="0"},"<border-width>":function(e){return this["<length>"](e)||ValidationTypes.isLiteral(e,"thin | medium | thick")},"<border-style>":function(e){return ValidationTypes.isLiteral(e,"none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset")},"<margin-width>":function(e){return this["<length>"](e)||this["<percentage>"](e)||ValidationTypes.isLiteral(e,"auto")},"<padding-width>":function(e){return this["<length>"](e)||this["<percentage>"](e)},"<shape>":function(e){return e.type=="function"&&(e.name=="rect"||e.name=="inset-rect")},"<time>":function(e){return e.type=="time"}},complex:{"<bg-position>":function(e){var t=this,n=!1,r="<percentage> | <length>",i="left | center | right",s="top | center | bottom",o,u,a;return ValidationTypes.isAny(e,"top | bottom")?n=!0:ValidationTypes.isAny(e,r)?e.hasNext()&&(n=ValidationTypes.isAny(e,r+" | "+s)):ValidationTypes.isAny(e,i)&&e.hasNext()&&(ValidationTypes.isAny(e,s)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,r)&&(ValidationTypes.isAny(e,s)&&ValidationTypes.isAny(e,r),n=!0)),n},"<bg-size>":function(e){var t=this,n=!1,r="<percentage> | <length> | auto",i,s,o;return ValidationTypes.isAny(e,"cover | contain")?n=!0:ValidationTypes.isAny(e,r)&&(n=!0,ValidationTypes.isAny(e,r)),n},"<repeat-style>":function(e){var t=!1,n="repeat | space | round | no-repeat",r;return e.hasNext()&&(r=e.next(),ValidationTypes.isLiteral(r,"repeat-x | repeat-y")?t=!0:ValidationTypes.isLiteral(r,n)&&(t=!0,e.hasNext()&&ValidationTypes.isLiteral(e.peek(),n)&&e.next())),t},"<shadow>":function(e){var t=!1,n=0,r=!1,i=!1,s;if(e.hasNext()){ValidationTypes.isAny(e,"inset")&&(r=!0),ValidationTypes.isAny(e,"<color>")&&(i=!0);while(ValidationTypes.isAny(e,"<length>")&&n<4)n++;e.hasNext()&&(i||ValidationTypes.isAny(e,"<color>"),r||ValidationTypes.isAny(e,"inset")),t=n>=2&&n<=4}return t},"<x-one-radius>":function(e){var t=!1,n=0,r="<length> | <percentage>",i;return ValidationTypes.isAny(e,r)&&(t=!0,ValidationTypes.isAny(e,r)),t}}};parserlib.css={Colors:Colors,Combinator:Combinator,Parser:Parser,PropertyName:PropertyName,PropertyValue:PropertyValue,PropertyValuePart:PropertyValuePart,MediaFeature:MediaFeature,MediaQuery:MediaQuery,Selector:Selector,SelectorPart:SelectorPart,SelectorSubPart:SelectorSubPart,Specificity:Specificity,TokenStream:TokenStream,Tokens:Tokens,ValidationError:ValidationError}}();var CSSLint=function(){var e=[],t=[],n=new parserlib.util.EventTarget;return n.version="0.9.9",n.addRule=function(t){e.push(t),e[t.id]=t},n.clearRules=function(){e=[]},n.getRules=function(){return[].concat(e).sort(function(e,t){return e.id>t.id?1:0})},n.getRuleset=function(){var t={},n=0,r=e.length;while(n<r)t[e[n++].id]=1;return t},n.addFormatter=function(e){t[e.id]=e},n.getFormatter=function(e){return t[e]},n.format=function(e,t,n,r){var i=this.getFormatter(n),s=null;return i&&(s=i.startFormat(),s+=i.formatResults(e,t,r||{}),s+=i.endFormat()),s},n.hasFormat=function(e){return t.hasOwnProperty(e)},n.verify=function(t,n){var r=0,i=e.length,s,o,u,a=new parserlib.css.Parser({starHack:!0,ieFilters:!0,underscoreHack:!0,strict:!1});o=t.replace(/\n\r?/g,"$split$").split("$split$"),n||(n=this.getRuleset()),s=new Reporter(o,n),n.errors=2;for(r in n)n.hasOwnProperty(r)&&e[r]&&e[r].init(a,s);try{a.parse(t)}catch(f){s.error("Fatal error, cannot continue: "+f.message,f.line,f.col,{})}return u={messages:s.messages,stats:s.stats},u.messages.sort(function(e,t){return e.rollup&&!t.rollup?1:!e.rollup&&t.rollup?-1:e.line-t.line}),u},n}();Reporter.prototype={constructor:Reporter,error:function(e,t,n,r){this.messages.push({type:"error",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r||{}})},warn:function(e,t,n,r){this.report(e,t,n,r)},report:function(e,t,n,r){this.messages.push({type:this.ruleset[r.id]==2?"error":"warning",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r})},info:function(e,t,n,r){this.messages.push({type:"info",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r})},rollupError:function(e,t){this.messages.push({type:"error",rollup:!0,message:e,rule:t})},rollupWarn:function(e,t){this.messages.push({type:"warning",rollup:!0,message:e,rule:t})},stat:function(e,t){this.stats[e]=t}},CSSLint._Reporter=Reporter,CSSLint.Util={mix:function(e,t){var n;for(n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return n},indexOf:function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},forEach:function(e,t){if(e.forEach)return e.forEach(t);for(var n=0,r=e.length;n<r;n++)t(e[n],n,e)}},CSSLint.addRule({id:"adjoining-classes",name:"Disallow adjoining classes",desc:"Don't use adjoining classes.",browsers:"IE6",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l,c;for(f=0;f<i.length;f++){s=i[f];for(l=0;l<s.parts.length;l++){o=s.parts[l];if(o.type==e.SELECTOR_PART_TYPE){a=0;for(c=0;c<o.modifiers.length;c++)u=o.modifiers[c],u.type=="class"&&a++,a>1&&t.report("Don't use adjoining classes.",o.line,o.col,n)}}}})}}),CSSLint.addRule({id:"box-model",name:"Beware of broken box size",desc:"Don't use width or height when using padding or border.",browsers:"All",init:function(e,t){function u(){s={},o=!1}function a(){var e,u;if(!o){if(s.height)for(e in i)i.hasOwnProperty(e)&&s[e]&&(u=s[e].value,(e!="padding"||u.parts.length!==2||u.parts[0].value!==0)&&t.report("Using height with "+e+" can sometimes make elements larger than you expect.",s[e].line,s[e].col,n));if(s.width)for(e in r)r.hasOwnProperty(e)&&s[e]&&(u=s[e].value,(e!="padding"||u.parts.length!==2||u.parts[1].value!==0)&&t.report("Using width with "+e+" can sometimes make elements larger than you expect.",s[e].line,s[e].col,n))}}var n=this,r={border:1,"border-left":1,"border-right":1,padding:1,"padding-left":1,"padding-right":1},i={border:1,"border-bottom":1,"border-top":1,padding:1,"padding-bottom":1,"padding-top":1},s,o=!1;e.addListener("startrule",u),e.addListener("startfontface",u),e.addListener("startpage",u),e.addListener("startpagemargin",u),e.addListener("startkeyframerule",u),e.addListener("property",function(e){var t=e.property.text.toLowerCase();i[t]||r[t]?!/^0\S*$/.test(e.value)&&(t!="border"||e.value!="none")&&(s[t]={line:e.property.line,col:e.property.col,value:e.value}):/^(width|height)/i.test(t)&&/^(length|percentage)/.test(e.value.parts[0].type)?s[t]=1:t=="box-sizing"&&(o=!0)}),e.addListener("endrule",a),e.addListener("endfontface",a),e.addListener("endpage",a),e.addListener("endpagemargin",a),e.addListener("endkeyframerule",a)}}),CSSLint.addRule({id:"box-sizing",name:"Disallow use of box-sizing",desc:"The box-sizing properties isn't supported in IE6 and IE7.",browsers:"IE6, IE7",tags:["Compatibility"],init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property.text.toLowerCase();r=="box-sizing"&&t.report("The box-sizing property isn't supported in IE6 and IE7.",e.line,e.col,n)})}}),CSSLint.addRule({id:"compatible-vendor-prefixes",name:"Require compatible vendor prefixes",desc:"Include all compatible vendor prefixes to reach a wider range of users.",browsers:"All",init:function(e,t){var n=this,r,i,s,o,u,a,f,l=!1,c=Array.prototype.push,h=[];r={animation:"webkit moz","animation-delay":"webkit moz","animation-direction":"webkit moz","animation-duration":"webkit moz","animation-fill-mode":"webkit moz","animation-iteration-count":"webkit moz","animation-name":"webkit moz","animation-play-state":"webkit moz","animation-timing-function":"webkit moz",appearance:"webkit moz","border-end":"webkit moz","border-end-color":"webkit moz","border-end-style":"webkit moz","border-end-width":"webkit moz","border-image":"webkit moz o","border-radius":"webkit moz","border-start":"webkit moz","border-start-color":"webkit moz","border-start-style":"webkit moz","border-start-width":"webkit moz","box-align":"webkit moz ms","box-direction":"webkit moz ms","box-flex":"webkit moz ms","box-lines":"webkit ms","box-ordinal-group":"webkit moz ms","box-orient":"webkit moz ms","box-pack":"webkit moz ms","box-sizing":"webkit moz","box-shadow":"webkit moz","column-count":"webkit moz ms","column-gap":"webkit moz ms","column-rule":"webkit moz ms","column-rule-color":"webkit moz ms","column-rule-style":"webkit moz ms","column-rule-width":"webkit moz ms","column-width":"webkit moz ms",hyphens:"epub moz","line-break":"webkit ms","margin-end":"webkit moz","margin-start":"webkit moz","marquee-speed":"webkit wap","marquee-style":"webkit wap","padding-end":"webkit moz","padding-start":"webkit moz","tab-size":"moz o","text-size-adjust":"webkit ms",transform:"webkit moz ms o","transform-origin":"webkit moz ms o",transition:"webkit moz o","transition-delay":"webkit moz o","transition-duration":"webkit moz o","transition-property":"webkit moz o","transition-timing-function":"webkit moz o","user-modify":"webkit moz","user-select":"webkit moz ms","word-break":"epub ms","writing-mode":"epub ms"};for(s in r)if(r.hasOwnProperty(s)){o=[],u=r[s].split(" ");for(a=0,f=u.length;a<f;a++)o.push("-"+u[a]+"-"+s);r[s]=o,c.apply(h,o)}e.addListener("startrule",function(){i=[]}),e.addListener("startkeyframes",function(e){l=e.prefix||!0}),e.addListener("endkeyframes",function(e){l=!1}),e.addListener("property",function(e){var t=e.property;CSSLint.Util.indexOf(h,t.text)>-1&&(!l||typeof l!="string"||t.text.indexOf("-"+l+"-")!==0)&&i.push(t)}),e.addListener("endrule",function(e){if(!i.length)return;var s={},o,u,a,f,l,c,h,p,d,v;for(o=0,u=i.length;o<u;o++){a=i[o];for(f in r)r.hasOwnProperty(f)&&(l=r[f],CSSLint.Util.indexOf(l,a.text)>-1&&(s[f]||(s[f]={full:l.slice(0),actual:[],actualNodes:[]}),CSSLint.Util.indexOf(s[f].actual,a.text)===-1&&(s[f].actual.push(a.text),s[f].actualNodes.push(a))))}for(f in s)if(s.hasOwnProperty(f)){c=s[f],h=c.full,p=c.actual;if(h.length>p.length)for(o=0,u=h.length;o<u;o++)d=h[o],CSSLint.Util.indexOf(p,d)===-1&&(v=p.length===1?p[0]:p.length==2?p.join(" and "):p.join(", "),t.report("The property "+d+" is compatible with "+v+" and should be included as well.",c.actualNodes[0].line,c.actualNodes[0].col,n))}})}}),CSSLint.addRule({id:"display-property-grouping",name:"Require properties appropriate for display",desc:"Certain properties shouldn't be used with certain display property values.",browsers:"All",init:function(e,t){function s(e,s,o){i[e]&&(typeof r[e]!="string"||i[e].value.toLowerCase()!=r[e])&&t.report(o||e+" can't be used with display: "+s+".",i[e].line,i[e].col,n)}function o(){i={}}function u(){var e=i.display?i.display.value:null;if(e)switch(e){case"inline":s("height",e),s("width",e),s("margin",e),s("margin-top",e),s("margin-bottom",e),s("float",e,"display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug).");break;case"block":s("vertical-align",e);break;case"inline-block":s("float",e);break;default:e.indexOf("table-")===0&&(s("margin",e),s("margin-left",e),s("margin-right",e),s("margin-top",e),s("margin-bottom",e),s("float",e))}}var n=this,r={display:1,"float":"none",height:1,width:1,margin:1,"margin-left":1,"margin-right":1,"margin-bottom":1,"margin-top":1,padding:1,"padding-left":1,"padding-right":1,"padding-bottom":1,"padding-top":1,"vertical-align":1},i;e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startkeyframerule",o),e.addListener("startpagemargin",o),e.addListener("startpage",o),e.addListener("property",function(e){var t=e.property.text.toLowerCase();r[t]&&(i[t]={value:e.value.text,line:e.property.line,col:e.property.col})}),e.addListener("endrule",u),e.addListener("endfontface",u),e.addListener("endkeyframerule",u),e.addListener("endpagemargin",u),e.addListener("endpage",u)}}),CSSLint.addRule({id:"duplicate-background-images",name:"Disallow duplicate background images",desc:"Every background-image should be unique. Use a common class for e.g. sprites.",browsers:"All",init:function(e,t){var n=this,r={};e.addListener("property",function(e){var i=e.property.text,s=e.value,o,u;if(i.match(/background/i))for(o=0,u=s.parts.length;o<u;o++)s.parts[o].type=="uri"&&(typeof r[s.parts[o].uri]=="undefined"?r[s.parts[o].uri]=e:t.report("Background image '"+s.parts[o].uri+"' was used multiple times, first declared at line "+r[s.parts[o].uri].line+", col "+r[s.parts[o].uri].col+".",e.line,e.col,n))})}}),CSSLint.addRule({id:"duplicate-properties",name:"Disallow duplicate properties",desc:"Duplicate properties must appear one after the other.",browsers:"All",init:function(e,t){function s(e){r={}}var n=this,r,i;e.addListener("startrule",s),e.addListener("startfontface",s),e.addListener("startpage",s),e.addListener("startpagemargin",s),e.addListener("startkeyframerule",s),e.addListener("property",function(e){var s=e.property,o=s.text.toLowerCase();r[o]&&(i!=o||r[o]==e.value.text)&&t.report("Duplicate property '"+e.property+"' found.",e.line,e.col,n),r[o]=e.value.text,i=o})}}),CSSLint.addRule({id:"empty-rules",name:"Disallow empty rules",desc:"Rules without any properties specified should be removed.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(){r=0}),e.addListener("property",function(){r++}),e.addListener("endrule",function(e){var i=e.selectors;r===0&&t.report("Rule is empty.",i[0].line,i[0].col,n)})}}),CSSLint.addRule({id:"errors",name:"Parsing Errors",desc:"This rule looks for recoverable syntax errors.",browsers:"All",init:function(e,t){var n=this;e.addListener("error",function(e){t.error(e.message,e.line,e.col,n)})}}),CSSLint.addRule({id:"fallback-colors",name:"Require fallback colors",desc:"For older browsers that don't support RGBA, HSL, or HSLA, provide a fallback color.",browsers:"IE6,IE7,IE8",init:function(e,t){function o(e){s={},r=null}var n=this,r,i={color:1,background:1,"background-color":1},s;e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startpage",o),e.addListener("startpagemargin",o),e.addListener("startkeyframerule",o),e.addListener("property",function(e){var s=e.property,o=s.text.toLowerCase(),u=e.value.parts,a=0,f="",l=u.length;if(i[o])while(a<l)u[a].type=="color"&&("alpha"in u[a]||"hue"in u[a]?(/([^\)]+)\(/.test(u[a])&&(f=RegExp.$1.toUpperCase()),(!r||r.property.text.toLowerCase()!=o||r.colorType!="compat")&&t.report("Fallback "+o+" (hex or RGB) should precede "+f+" "+o+".",e.line,e.col,n)):e.colorType="compat"),a++;r=e})}}),CSSLint.addRule({id:"floats",name:"Disallow too many floats",desc:"This rule tests if the float property is used too many times",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.property.text.toLowerCase()=="float"&&e.value.text.toLowerCase()!="none"&&r++}),e.addListener("endstylesheet",function(){t.stat("floats",r),r>=10&&t.rollupWarn("Too many floats ("+r+"), you're probably using them for layout. Consider using a grid system instead.",n)})}}),CSSLint.addRule({id:"font-faces",name:"Don't use too many web fonts",desc:"Too many different web fonts in the same stylesheet.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("startfontface",function(){r++}),e.addListener("endstylesheet",function(){r>5&&t.rollupWarn("Too many @font-face declarations ("+r+").",n)})}}),CSSLint.addRule({id:"font-sizes",name:"Disallow too many font sizes",desc:"Checks the number of font-size declarations.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.property=="font-size"&&r++}),e.addListener("endstylesheet",function(){t.stat("font-sizes",r),r>=10&&t.rollupWarn("Too many font-size declarations ("+r+"), abstraction needed.",n)})}}),CSSLint.addRule({id:"gradients",name:"Require all gradient definitions",desc:"When using a vendor-prefixed gradient, make sure to use them all.",browsers:"All",init:function(e,t){var n=this,r;e.addListener("startrule",function(){r={moz:0,webkit:0,oldWebkit:0,ms:0,o:0}}),e.addListener("property",function(e){/\-(moz|ms|o|webkit)(?:\-(?:linear|radial))\-gradient/i.test(e.value)?r[RegExp.$1]=1:/\-webkit\-gradient/i.test(e.value)&&(r.oldWebkit=1)}),e.addListener("endrule",function(e){var i=[];r.moz||i.push("Firefox 3.6+"),r.webkit||i.push("Webkit (Safari 5+, Chrome)"),r.oldWebkit||i.push("Old Webkit (Safari 4+, Chrome)"),r.ms||i.push("Internet Explorer 10+"),r.o||i.push("Opera 11.1+"),i.length&&i.length<5&&t.report("Missing vendor-prefixed CSS gradients for "+i.join(", ")+".",e.selectors[0].line,e.selectors[0].col,n)})}}),CSSLint.addRule({id:"ids",name:"Disallow IDs in selectors",desc:"Selectors should not contain IDs.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l,c;for(f=0;f<i.length;f++){s=i[f],a=0;for(l=0;l<s.parts.length;l++){o=s.parts[l];if(o.type==e.SELECTOR_PART_TYPE)for(c=0;c<o.modifiers.length;c++)u=o.modifiers[c],u.type=="id"&&a++}a==1?t.report("Don't use IDs in selectors.",s.line,s.col,n):a>1&&t.report(a+" IDs in the selector, really?",s.line,s.col,n)}})}}),CSSLint.addRule({id:"import",name:"Disallow @import",desc:"Don't use @import, use <link> instead.",browsers:"All",init:function(e,t){var n=this;e.addListener("import",function(e){t.report("@import prevents parallel downloads, use <link> instead.",e.line,e.col,n)})}}),CSSLint.addRule({id:"important",name:"Disallow !important",desc:"Be careful when using !important declaration",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.important===!0&&(r++,t.report("Use of !important",e.line,e.col,n))}),e.addListener("endstylesheet",function(){t.stat("important",r),r>=10&&t.rollupWarn("Too many !important declarations ("+r+"), try to use less than 10 to avoid specificity issues.",n)})}}),CSSLint.addRule({id:"known-properties",name:"Require use of known properties",desc:"Properties should be known (listed in CSS3 specification) or be a vendor-prefixed property.",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property.text.toLowerCase();e.invalid&&t.report(e.invalid.message,e.line,e.col,n)})}}),CSSLint.addRule({id:"outline-none",name:"Disallow outline: none",desc:"Use of outline: none or outline: 0 should be limited to :focus rules.",browsers:"All",tags:["Accessibility"],init:function(e,t){function i(e){e.selectors?r={line:e.line,col:e.col,selectors:e.selectors,propCount:0,outline:!1}:r=null}function s(e){r&&r.outline&&(r.selectors.toString().toLowerCase().indexOf(":focus")==-1?t.report("Outlines should only be modified using :focus.",r.line,r.col,n):r.propCount==1&&t.report("Outlines shouldn't be hidden unless other visual changes are made.",r.line,r.col,n))}var n=this,r;e.addListener("startrule",i),e.addListener("startfontface",i),e.addListener("startpage",i),e.addListener("startpagemargin",i),e.addListener("startkeyframerule",i),e.addListener("property",function(e){var t=e.property.text.toLowerCase(),n=e.value;r&&(r.propCount++,t=="outline"&&(n=="none"||n=="0")&&(r.outline=!0))}),e.addListener("endrule",s),e.addListener("endfontface",s),e.addListener("endpage",s),e.addListener("endpagemargin",s),e.addListener("endkeyframerule",s)}}),CSSLint.addRule({id:"overqualified-elements",name:"Disallow overqualified elements",desc:"Don't use classes or IDs with elements (a.foo or a#foo).",browsers:"All",init:function(e,t){var n=this,r={};e.addListener("startrule",function(i){var s=i.selectors,o,u,a,f,l,c;for(f=0;f<s.length;f++){o=s[f];for(l=0;l<o.parts.length;l++){u=o.parts[l];if(u.type==e.SELECTOR_PART_TYPE)for(c=0;c<u.modifiers.length;c++)a=u.modifiers[c],u.elementName&&a.type=="id"?t.report("Element ("+u+") is overqualified, just use "+a+" without element name.",u.line,u.col,n):a.type=="class"&&(r[a]||(r[a]=[]),r[a].push({modifier:a,part:u}))}}}),e.addListener("endstylesheet",function(){var e;for(e in r)r.hasOwnProperty(e)&&r[e].length==1&&r[e][0].part.elementName&&t.report("Element ("+r[e][0].part+") is overqualified, just use "+r[e][0].modifier+" without element name.",r[e][0].part.line,r[e][0].part.col,n)})}}),CSSLint.addRule({id:"qualified-headings",name:"Disallow qualified headings",desc:"Headings should not be qualified (namespaced).",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a;for(u=0;u<i.length;u++){s=i[u];for(a=0;a<s.parts.length;a++)o=s.parts[a],o.type==e.SELECTOR_PART_TYPE&&o.elementName&&/h[1-6]/.test(o.elementName.toString())&&a>0&&t.report("Heading ("+o.elementName+") should not be qualified.",o.line,o.col,n)}})}}),CSSLint.addRule({id:"regex-selectors",name:"Disallow selectors that look like regexs",desc:"Selectors that look like regular expressions are slow and should be avoided.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l;for(a=0;a<i.length;a++){s=i[a];for(f=0;f<s.parts.length;f++){o=s.parts[f];if(o.type==e.SELECTOR_PART_TYPE)for(l=0;l<o.modifiers.length;l++)u=o.modifiers[l],u.type=="attribute"&&/([\~\|\^\$\*]=)/.test(u)&&t.report("Attribute selectors with "+RegExp.$1+" are slow!",u.line,u.col,n)}}})}}),CSSLint.addRule({id:"rules-count",name:"Rules Count",desc:"Track how many rules there are.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(){r++}),e.addListener("endstylesheet",function(){t.stat("rule-count",r)})}}),CSSLint.addRule({id:"shorthand",name:"Require shorthand properties",desc:"Use shorthand properties where possible.",browsers:"All",init:function(e,t){function f(e){u={}}function l(e){var r,i,s,o;for(r in a)if(a.hasOwnProperty(r)){o=0;for(i=0,s=a[r].length;i<s;i++)o+=u[a[r][i]]?1:0;o==a[r].length&&t.report("The properties "+a[r].join(", ")+" can be replaced by "+r+".",e.line,e.col,n)}}var n=this,r,i,s,o={},u,a={margin:["margin-top","margin-bottom","margin-left","margin-right"],padding:["padding-top","padding-bottom","padding-left","padding-right"]};for(r in a)if(a.hasOwnProperty(r))for(i=0,s=a[r].length;i<s;i++)o[a[r][i]]=r;e.addListener("startrule",f),e.addListener("startfontface",f),e.addListener("property",function(e){var t=e.property.toString().toLowerCase(),n=e.value.parts[0].value;o[t]&&(u[t]=1)}),e.addListener("endrule",l),e.addListener("endfontface",l)}}),CSSLint.addRule({id:"star-property-hack",name:"Disallow properties with a star prefix",desc:"Checks for the star property hack (targets IE6/7)",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property;r.hack=="*"&&t.report("Property with star prefix found.",e.property.line,e.property.col,n)})}}),CSSLint.addRule({id:"text-indent",name:"Disallow negative text-indent",desc:"Checks for text indent less than -99px",browsers:"All",init:function(e,t){function s(e){r=!1,i="inherit"}function o(e){r&&i!="ltr"&&t.report("Negative text-indent doesn't work well with RTL. If you use text-indent for image replacement explicitly set direction for that item to ltr.",r.line,r.col,n)}var n=this,r,i;e.addListener("startrule",s),e.addListener("startfontface",s),e.addListener("property",function(e){var t=e.property.toString().toLowerCase(),n=e.value;t=="text-indent"&&n.parts[0].value<-99?r=e.property:t=="direction"&&n=="ltr"&&(i="ltr")}),e.addListener("endrule",o),e.addListener("endfontface",o)}}),CSSLint.addRule({id:"underscore-property-hack",name:"Disallow properties with an underscore prefix",desc:"Checks for the underscore property hack (targets IE6)",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property;r.hack=="_"&&t.report("Property with underscore prefix found.",e.property.line,e.property.col,n)})}}),CSSLint.addRule({id:"unique-headings",name:"Headings should only be defined once",desc:"Headings should be defined only once.",browsers:"All",init:function(e,t){var n=this,r={h1:0,h2:0,h3:0,h4:0,h5:0,h6:0};e.addListener("startrule",function(e){var i=e.selectors,s,o,u,a,f;for(a=0;a<i.length;a++){s=i[a],o=s.parts[s.parts.length-1];if(o.elementName&&/(h[1-6])/i.test(o.elementName.toString())){for(f=0;f<o.modifiers.length;f++)if(o.modifiers[f].type=="pseudo"){u=!0;break}u||(r[RegExp.$1]++,r[RegExp.$1]>1&&t.report("Heading ("+o.elementName+") has already been defined.",o.line,o.col,n))}}}),e.addListener("endstylesheet",function(e){var i,s=[];for(i in r)r.hasOwnProperty(i)&&r[i]>1&&s.push(r[i]+" "+i+"s");s.length&&t.rollupWarn("You have "+s.join(", ")+" defined in this stylesheet.",n)})}}),CSSLint.addRule({id:"universal-selector",name:"Disallow universal selector",desc:"The universal selector (*) is known to be slow.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(e){var r=e.selectors,i,s,o,u,a,f;for(u=0;u<r.length;u++)i=r[u],s=i.parts[i.parts.length-1],s.elementName=="*"&&t.report(n.desc,s.line,s.col,n)})}}),CSSLint.addRule({id:"unqualified-attributes",name:"Disallow unqualified attribute selectors",desc:"Unqualified attribute selectors are known to be slow.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l;for(a=0;a<i.length;a++){s=i[a],o=s.parts[s.parts.length-1];if(o.type==e.SELECTOR_PART_TYPE)for(l=0;l<o.modifiers.length;l++)u=o.modifiers[l],u.type=="attribute"&&(!o.elementName||o.elementName=="*")&&t.report(n.desc,o.line,o.col,n)}})}}),CSSLint.addRule({id:"vendor-prefix",name:"Require standard property with vendor prefix",desc:"When using a vendor-prefixed property, make sure to include the standard one.",browsers:"All",init:function(e,t){function o(){r={},i=1}function u(e){var i,o,u,a,f,l,c=[];for(i in r)s[i]&&c.push({actual:i,needed:s[i]});for(o=0,u=c.length;o<u;o++)f=c[o].needed,l=c[o].actual,r[f]?r[f][0].pos<r[l][0].pos&&t.report("Standard property '"+f+"' should come after vendor-prefixed property '"+l+"'.",r[l][0].name.line,r[l][0].name.col,n):t.report("Missing standard property '"+f+"' to go along with '"+l+"'.",r[l][0].name.line,r[l][0].name.col,n)}var n=this,r,i,s={"-webkit-border-radius":"border-radius","-webkit-border-top-left-radius":"border-top-left-radius","-webkit-border-top-right-radius":"border-top-right-radius","-webkit-border-bottom-left-radius":"border-bottom-left-radius","-webkit-border-bottom-right-radius":"border-bottom-right-radius","-o-border-radius":"border-radius","-o-border-top-left-radius":"border-top-left-radius","-o-border-top-right-radius":"border-top-right-radius","-o-border-bottom-left-radius":"border-bottom-left-radius","-o-border-bottom-right-radius":"border-bottom-right-radius","-moz-border-radius":"border-radius","-moz-border-radius-topleft":"border-top-left-radius","-moz-border-radius-topright":"border-top-right-radius","-moz-border-radius-bottomleft":"border-bottom-left-radius","-moz-border-radius-bottomright":"border-bottom-right-radius","-moz-column-count":"column-count","-webkit-column-count":"column-count","-moz-column-gap":"column-gap","-webkit-column-gap":"column-gap","-moz-column-rule":"column-rule","-webkit-column-rule":"column-rule","-moz-column-rule-style":"column-rule-style","-webkit-column-rule-style":"column-rule-style","-moz-column-rule-color":"column-rule-color","-webkit-column-rule-color":"column-rule-color","-moz-column-rule-width":"column-rule-width","-webkit-column-rule-width":"column-rule-width","-moz-column-width":"column-width","-webkit-column-width":"column-width","-webkit-column-span":"column-span","-webkit-columns":"columns","-moz-box-shadow":"box-shadow","-webkit-box-shadow":"box-shadow","-moz-transform":"transform","-webkit-transform":"transform","-o-transform":"transform","-ms-transform":"transform","-moz-transform-origin":"transform-origin","-webkit-transform-origin":"transform-origin","-o-transform-origin":"transform-origin","-ms-transform-origin":"transform-origin","-moz-box-sizing":"box-sizing","-webkit-box-sizing":"box-sizing","-moz-user-select":"user-select","-khtml-user-select":"user-select","-webkit-user-select":"user-select"};e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startpage",o),e.addListener("startpagemargin",o),e.addListener("startkeyframerule",o),e.addListener("property",function(e){var t=e.property.text.toLowerCase();r[t]||(r[t]=[]),r[t].push({name:e.property,value:e.value,pos:i++})}),e.addListener("endrule",u),e.addListener("endfontface",u),e.addListener("endpage",u),e.addListener("endpagemargin",u),e.addListener("endkeyframerule",u)}}),CSSLint.addRule({id:"zero-units",name:"Disallow units for 0 values",desc:"You don't need to specify units when a value is 0.",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.value.parts,i=0,s=r.length;while(i<s)(r[i].units||r[i].type=="percentage")&&r[i].value===0&&r[i].type!="time"&&t.report("Values of 0 shouldn't have units specified.",r[i].line,r[i].col,n),i++})}}),exports.CSSLint=CSSLint}) \ No newline at end of file
+"no use strict";
+
+if (typeof window != "undefined" && window.document)
+ throw "atempt to load ace worker into main window instead of webWorker";
+
+var console = {
+ log: function() {
+ var msgs = Array.prototype.slice.call(arguments, 0);
+ postMessage({type: "log", data: msgs});
+ },
+ error: function() {
+ var msgs = Array.prototype.slice.call(arguments, 0);
+ postMessage({type: "log", data: msgs});
+ }
+};
+var window = {
+ console: console
+};
+
+var normalizeModule = function(parentId, moduleName) {
+ // normalize plugin requires
+ if (moduleName.indexOf("!") !== -1) {
+ var chunks = moduleName.split("!");
+ return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
+ }
+ // normalize relative requires
+ if (moduleName.charAt(0) == ".") {
+ var base = parentId.split("/").slice(0, -1).join("/");
+ moduleName = base + "/" + moduleName;
+
+ while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
+ var previous = moduleName;
+ moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
+ }
+ }
+
+ return moduleName;
+};
+
+var require = function(parentId, id) {
+ if (!id.charAt)
+ throw new Error("worker.js require() accepts only (parentId, id) as arguments");
+
+ id = normalizeModule(parentId, id);
+
+ var module = require.modules[id];
+ if (module) {
+ if (!module.initialized) {
+ module.initialized = true;
+ module.exports = module.factory().exports;
+ }
+ return module.exports;
+ }
+
+ var chunks = id.split("/");
+ chunks[0] = require.tlns[chunks[0]] || chunks[0];
+ var path = chunks.join("/") + ".js";
+
+ require.id = id;
+ importScripts(path);
+ return require(parentId, id);
+};
+
+require.modules = {};
+require.tlns = {};
+
+var define = function(id, deps, factory) {
+ if (arguments.length == 2) {
+ factory = deps;
+ if (typeof id != "string") {
+ deps = id;
+ id = require.id;
+ }
+ } else if (arguments.length == 1) {
+ factory = id;
+ id = require.id;
+ }
+
+ if (id.indexOf("text!") === 0)
+ return;
+
+ var req = function(deps, factory) {
+ return require(id, deps, factory);
+ };
+
+ require.modules[id] = {
+ factory: function() {
+ var module = {
+ exports: {}
+ };
+ var returnExports = factory(req, module.exports, module);
+ if (returnExports)
+ module.exports = returnExports;
+ return module;
+ }
+ };
+};
+
+function initBaseUrls(topLevelNamespaces) {
+ require.tlns = topLevelNamespaces;
+}
+
+function initSender() {
+
+ var EventEmitter = require(null, "ace/lib/event_emitter").EventEmitter;
+ var oop = require(null, "ace/lib/oop");
+
+ var Sender = function() {};
+
+ (function() {
+
+ oop.implement(this, EventEmitter);
+
+ this.callback = function(data, callbackId) {
+ postMessage({
+ type: "call",
+ id: callbackId,
+ data: data
+ });
+ };
+
+ this.emit = function(name, data) {
+ postMessage({
+ type: "event",
+ name: name,
+ data: data
+ });
+ };
+
+ }).call(Sender.prototype);
+
+ return new Sender();
+}
+
+var main;
+var sender;
+
+onmessage = function(e) {
+ var msg = e.data;
+ if (msg.command) {
+ if (main[msg.command])
+ main[msg.command].apply(main, msg.args);
+ else
+ throw new Error("Unknown command:" + msg.command);
+ }
+ else if (msg.init) {
+ initBaseUrls(msg.tlns);
+ require(null, "ace/lib/fixoldbrowsers");
+ sender = initSender();
+ var clazz = require(null, msg.module)[msg.classname];
+ main = new clazz(sender);
+ }
+ else if (msg.event && sender) {
+ sender._emit(msg.event, msg.data);
+ }
+};
+// vim:set ts=4 sts=4 sw=4 st:
+
+define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/regexp', 'ace/lib/es5-shim'], function(require, exports, module) {
+
+
+require("./regexp");
+require("./es5-shim");
+
+});
+
+define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, exports, module) {
+
+ var real = {
+ exec: RegExp.prototype.exec,
+ test: RegExp.prototype.test,
+ match: String.prototype.match,
+ replace: String.prototype.replace,
+ split: String.prototype.split
+ },
+ compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
+ compliantLastIndexIncrement = function () {
+ var x = /^/g;
+ real.test.call(x, "");
+ return !x.lastIndex;
+ }();
+
+ if (compliantLastIndexIncrement && compliantExecNpcg)
+ return;
+ RegExp.prototype.exec = function (str) {
+ var match = real.exec.apply(this, arguments),
+ name, r2;
+ if ( typeof(str) == 'string' && match) {
+ if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
+ r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
+ real.replace.call(str.slice(match.index), r2, function () {
+ for (var i = 1; i < arguments.length - 2; i++) {
+ if (arguments[i] === undefined)
+ match[i] = undefined;
+ }
+ });
+ }
+ if (this._xregexp && this._xregexp.captureNames) {
+ for (var i = 1; i < match.length; i++) {
+ name = this._xregexp.captureNames[i - 1];
+ if (name)
+ match[name] = match[i];
+ }
+ }
+ if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
+ this.lastIndex--;
+ }
+ return match;
+ };
+ if (!compliantLastIndexIncrement) {
+ RegExp.prototype.test = function (str) {
+ var match = real.exec.call(this, str);
+ if (match && this.global && !match[0].length && (this.lastIndex > match.index))
+ this.lastIndex--;
+ return !!match;
+ };
+ }
+
+ function getNativeFlags (regex) {
+ return (regex.global ? "g" : "") +
+ (regex.ignoreCase ? "i" : "") +
+ (regex.multiline ? "m" : "") +
+ (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3
+ (regex.sticky ? "y" : "");
+ }
+
+ function indexOf (array, item, from) {
+ if (Array.prototype.indexOf) // Use the native array method if available
+ return array.indexOf(item, from);
+ for (var i = from || 0; i < array.length; i++) {
+ if (array[i] === item)
+ return i;
+ }
+ return -1;
+ }
+
+});
+
+define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
+
+function Empty() {}
+
+if (!Function.prototype.bind) {
+ Function.prototype.bind = function bind(that) { // .length is 1
+ var target = this;
+ if (typeof target != "function") {
+ throw new TypeError("Function.prototype.bind called on incompatible " + target);
+ }
+ var args = slice.call(arguments, 1); // for normal call
+ var bound = function () {
+
+ if (this instanceof bound) {
+
+ var result = target.apply(
+ this,
+ args.concat(slice.call(arguments))
+ );
+ if (Object(result) === result) {
+ return result;
+ }
+ return this;
+
+ } else {
+ return target.apply(
+ that,
+ args.concat(slice.call(arguments))
+ );
+
+ }
+
+ };
+ if(target.prototype) {
+ Empty.prototype = target.prototype;
+ bound.prototype = new Empty();
+ Empty.prototype = null;
+ }
+ return bound;
+ };
+}
+var call = Function.prototype.call;
+var prototypeOfArray = Array.prototype;
+var prototypeOfObject = Object.prototype;
+var slice = prototypeOfArray.slice;
+var _toString = call.bind(prototypeOfObject.toString);
+var owns = call.bind(prototypeOfObject.hasOwnProperty);
+var defineGetter;
+var defineSetter;
+var lookupGetter;
+var lookupSetter;
+var supportsAccessors;
+if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
+ defineGetter = call.bind(prototypeOfObject.__defineGetter__);
+ defineSetter = call.bind(prototypeOfObject.__defineSetter__);
+ lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
+ lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
+}
+if ([1,2].splice(0).length != 2) {
+ if(function() { // test IE < 9 to splice bug - see issue #138
+ function makeArray(l) {
+ var a = new Array(l+2);
+ a[0] = a[1] = 0;
+ return a;
+ }
+ var array = [], lengthBefore;
+
+ array.splice.apply(array, makeArray(20));
+ array.splice.apply(array, makeArray(26));
+
+ lengthBefore = array.length; //46
+ array.splice(5, 0, "XXX"); // add one element
+
+ lengthBefore + 1 == array.length
+
+ if (lengthBefore + 1 == array.length) {
+ return true;// has right splice implementation without bugs
+ }
+ }()) {//IE 6/7
+ var array_splice = Array.prototype.splice;
+ Array.prototype.splice = function(start, deleteCount) {
+ if (!arguments.length) {
+ return [];
+ } else {
+ return array_splice.apply(this, [
+ start === void 0 ? 0 : start,
+ deleteCount === void 0 ? (this.length - start) : deleteCount
+ ].concat(slice.call(arguments, 2)))
+ }
+ };
+ } else {//IE8
+ Array.prototype.splice = function(pos, removeCount){
+ var length = this.length;
+ if (pos > 0) {
+ if (pos > length)
+ pos = length;
+ } else if (pos == void 0) {
+ pos = 0;
+ } else if (pos < 0) {
+ pos = Math.max(length + pos, 0);
+ }
+
+ if (!(pos+removeCount < length))
+ removeCount = length - pos;
+
+ var removed = this.slice(pos, pos+removeCount);
+ var insert = slice.call(arguments, 2);
+ var add = insert.length;
+ if (pos === length) {
+ if (add) {
+ this.push.apply(this, insert);
+ }
+ } else {
+ var remove = Math.min(removeCount, length - pos);
+ var tailOldPos = pos + remove;
+ var tailNewPos = tailOldPos + add - remove;
+ var tailCount = length - tailOldPos;
+ var lengthAfterRemove = length - remove;
+
+ if (tailNewPos < tailOldPos) { // case A
+ for (var i = 0; i < tailCount; ++i) {
+ this[tailNewPos+i] = this[tailOldPos+i];
+ }
+ } else if (tailNewPos > tailOldPos) { // case B
+ for (i = tailCount; i--; ) {
+ this[tailNewPos+i] = this[tailOldPos+i];
+ }
+ } // else, add == remove (nothing to do)
+
+ if (add && pos === lengthAfterRemove) {
+ this.length = lengthAfterRemove; // truncate array
+ this.push.apply(this, insert);
+ } else {
+ this.length = lengthAfterRemove + add; // reserves space
+ for (i = 0; i < add; ++i) {
+ this[pos+i] = insert[i];
+ }
+ }
+ }
+ return removed;
+ };
+ }
+}
+if (!Array.isArray) {
+ Array.isArray = function isArray(obj) {
+ return _toString(obj) == "[object Array]";
+ };
+}
+var boxedString = Object("a"),
+ splitString = boxedString[0] != "a" || !(0 in boxedString);
+
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function forEach(fun /*, thisp*/) {
+ var object = toObject(this),
+ self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ object,
+ thisp = arguments[1],
+ i = -1,
+ length = self.length >>> 0;
+ if (_toString(fun) != "[object Function]") {
+ throw new TypeError(); // TODO message
+ }
+
+ while (++i < length) {
+ if (i in self) {
+ fun.call(thisp, self[i], i, object);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function map(fun /*, thisp*/) {
+ var object = toObject(this),
+ self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0,
+ result = Array(length),
+ thisp = arguments[1];
+ if (_toString(fun) != "[object Function]") {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self)
+ result[i] = fun.call(thisp, self[i], i, object);
+ }
+ return result;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function filter(fun /*, thisp */) {
+ var object = toObject(this),
+ self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0,
+ result = [],
+ value,
+ thisp = arguments[1];
+ if (_toString(fun) != "[object Function]") {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self) {
+ value = self[i];
+ if (fun.call(thisp, value, i, object)) {
+ result.push(value);
+ }
+ }
+ }
+ return result;
+ };
+}
+if (!Array.prototype.every) {
+ Array.prototype.every = function every(fun /*, thisp */) {
+ var object = toObject(this),
+ self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0,
+ thisp = arguments[1];
+ if (_toString(fun) != "[object Function]") {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self && !fun.call(thisp, self[i], i, object)) {
+ return false;
+ }
+ }
+ return true;
+ };
+}
+if (!Array.prototype.some) {
+ Array.prototype.some = function some(fun /*, thisp */) {
+ var object = toObject(this),
+ self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0,
+ thisp = arguments[1];
+ if (_toString(fun) != "[object Function]") {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self && fun.call(thisp, self[i], i, object)) {
+ return true;
+ }
+ }
+ return false;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function reduce(fun /*, initial*/) {
+ var object = toObject(this),
+ self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0;
+ if (_toString(fun) != "[object Function]") {
+ throw new TypeError(fun + " is not a function");
+ }
+ if (!length && arguments.length == 1) {
+ throw new TypeError("reduce of empty array with no initial value");
+ }
+
+ var i = 0;
+ var result;
+ if (arguments.length >= 2) {
+ result = arguments[1];
+ } else {
+ do {
+ if (i in self) {
+ result = self[i++];
+ break;
+ }
+ if (++i >= length) {
+ throw new TypeError("reduce of empty array with no initial value");
+ }
+ } while (true);
+ }
+
+ for (; i < length; i++) {
+ if (i in self) {
+ result = fun.call(void 0, result, self[i], i, object);
+ }
+ }
+
+ return result;
+ };
+}
+if (!Array.prototype.reduceRight) {
+ Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
+ var object = toObject(this),
+ self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0;
+ if (_toString(fun) != "[object Function]") {
+ throw new TypeError(fun + " is not a function");
+ }
+ if (!length && arguments.length == 1) {
+ throw new TypeError("reduceRight of empty array with no initial value");
+ }
+
+ var result, i = length - 1;
+ if (arguments.length >= 2) {
+ result = arguments[1];
+ } else {
+ do {
+ if (i in self) {
+ result = self[i--];
+ break;
+ }
+ if (--i < 0) {
+ throw new TypeError("reduceRight of empty array with no initial value");
+ }
+ } while (true);
+ }
+
+ do {
+ if (i in this) {
+ result = fun.call(void 0, result, self[i], i, object);
+ }
+ } while (i--);
+
+ return result;
+ };
+}
+if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
+ Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
+ var self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ toObject(this),
+ length = self.length >>> 0;
+
+ if (!length) {
+ return -1;
+ }
+
+ var i = 0;
+ if (arguments.length > 1) {
+ i = toInteger(arguments[1]);
+ }
+ i = i >= 0 ? i : Math.max(0, length + i);
+ for (; i < length; i++) {
+ if (i in self && self[i] === sought) {
+ return i;
+ }
+ }
+ return -1;
+ };
+}
+if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
+ Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
+ var self = splitString && _toString(this) == "[object String]" ?
+ this.split("") :
+ toObject(this),
+ length = self.length >>> 0;
+
+ if (!length) {
+ return -1;
+ }
+ var i = length - 1;
+ if (arguments.length > 1) {
+ i = Math.min(i, toInteger(arguments[1]));
+ }
+ i = i >= 0 ? i : length - Math.abs(i);
+ for (; i >= 0; i--) {
+ if (i in self && sought === self[i]) {
+ return i;
+ }
+ }
+ return -1;
+ };
+}
+if (!Object.getPrototypeOf) {
+ Object.getPrototypeOf = function getPrototypeOf(object) {
+ return object.__proto__ || (
+ object.constructor ?
+ object.constructor.prototype :
+ prototypeOfObject
+ );
+ };
+}
+if (!Object.getOwnPropertyDescriptor) {
+ var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
+ "non-object: ";
+ Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
+ if ((typeof object != "object" && typeof object != "function") || object === null)
+ throw new TypeError(ERR_NON_OBJECT + object);
+ if (!owns(object, property))
+ return;
+
+ var descriptor, getter, setter;
+ descriptor = { enumerable: true, configurable: true };
+ if (supportsAccessors) {
+ var prototype = object.__proto__;
+ object.__proto__ = prototypeOfObject;
+
+ var getter = lookupGetter(object, property);
+ var setter = lookupSetter(object, property);
+ object.__proto__ = prototype;
+
+ if (getter || setter) {
+ if (getter) descriptor.get = getter;
+ if (setter) descriptor.set = setter;
+ return descriptor;
+ }
+ }
+ descriptor.value = object[property];
+ return descriptor;
+ };
+}
+if (!Object.getOwnPropertyNames) {
+ Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
+ return Object.keys(object);
+ };
+}
+if (!Object.create) {
+ var createEmpty;
+ if (Object.prototype.__proto__ === null) {
+ createEmpty = function () {
+ return { "__proto__": null };
+ };
+ } else {
+ createEmpty = function () {
+ var empty = {};
+ for (var i in empty)
+ empty[i] = null;
+ empty.constructor =
+ empty.hasOwnProperty =
+ empty.propertyIsEnumerable =
+ empty.isPrototypeOf =
+ empty.toLocaleString =
+ empty.toString =
+ empty.valueOf =
+ empty.__proto__ = null;
+ return empty;
+ }
+ }
+
+ Object.create = function create(prototype, properties) {
+ var object;
+ if (prototype === null) {
+ object = createEmpty();
+ } else {
+ if (typeof prototype != "object")
+ throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
+ var Type = function () {};
+ Type.prototype = prototype;
+ object = new Type();
+ object.__proto__ = prototype;
+ }
+ if (properties !== void 0)
+ Object.defineProperties(object, properties);
+ return object;
+ };
+}
+
+function doesDefinePropertyWork(object) {
+ try {
+ Object.defineProperty(object, "sentinel", {});
+ return "sentinel" in object;
+ } catch (exception) {
+ }
+}
+if (Object.defineProperty) {
+ var definePropertyWorksOnObject = doesDefinePropertyWork({});
+ var definePropertyWorksOnDom = typeof document == "undefined" ||
+ doesDefinePropertyWork(document.createElement("div"));
+ if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
+ var definePropertyFallback = Object.defineProperty;
+ }
+}
+
+if (!Object.defineProperty || definePropertyFallback) {
+ var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
+ var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
+ var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
+ "on this javascript engine";
+
+ Object.defineProperty = function defineProperty(object, property, descriptor) {
+ if ((typeof object != "object" && typeof object != "function") || object === null)
+ throw new TypeError(ERR_NON_OBJECT_TARGET + object);
+ if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
+ throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
+ if (definePropertyFallback) {
+ try {
+ return definePropertyFallback.call(Object, object, property, descriptor);
+ } catch (exception) {
+ }
+ }
+ if (owns(descriptor, "value")) {
+
+ if (supportsAccessors && (lookupGetter(object, property) ||
+ lookupSetter(object, property)))
+ {
+ var prototype = object.__proto__;
+ object.__proto__ = prototypeOfObject;
+ delete object[property];
+ object[property] = descriptor.value;
+ object.__proto__ = prototype;
+ } else {
+ object[property] = descriptor.value;
+ }
+ } else {
+ if (!supportsAccessors)
+ throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
+ if (owns(descriptor, "get"))
+ defineGetter(object, property, descriptor.get);
+ if (owns(descriptor, "set"))
+ defineSetter(object, property, descriptor.set);
+ }
+
+ return object;
+ };
+}
+if (!Object.defineProperties) {
+ Object.defineProperties = function defineProperties(object, properties) {
+ for (var property in properties) {
+ if (owns(properties, property))
+ Object.defineProperty(object, property, properties[property]);
+ }
+ return object;
+ };
+}
+if (!Object.seal) {
+ Object.seal = function seal(object) {
+ return object;
+ };
+}
+if (!Object.freeze) {
+ Object.freeze = function freeze(object) {
+ return object;
+ };
+}
+try {
+ Object.freeze(function () {});
+} catch (exception) {
+ Object.freeze = (function freeze(freezeObject) {
+ return function freeze(object) {
+ if (typeof object == "function") {
+ return object;
+ } else {
+ return freezeObject(object);
+ }
+ };
+ })(Object.freeze);
+}
+if (!Object.preventExtensions) {
+ Object.preventExtensions = function preventExtensions(object) {
+ return object;
+ };
+}
+if (!Object.isSealed) {
+ Object.isSealed = function isSealed(object) {
+ return false;
+ };
+}
+if (!Object.isFrozen) {
+ Object.isFrozen = function isFrozen(object) {
+ return false;
+ };
+}
+if (!Object.isExtensible) {
+ Object.isExtensible = function isExtensible(object) {
+ if (Object(object) === object) {
+ throw new TypeError(); // TODO message
+ }
+ var name = '';
+ while (owns(object, name)) {
+ name += '?';
+ }
+ object[name] = true;
+ var returnValue = owns(object, name);
+ delete object[name];
+ return returnValue;
+ };
+}
+if (!Object.keys) {
+ var hasDontEnumBug = true,
+ dontEnums = [
+ "toString",
+ "toLocaleString",
+ "valueOf",
+ "hasOwnProperty",
+ "isPrototypeOf",
+ "propertyIsEnumerable",
+ "constructor"
+ ],
+ dontEnumsLength = dontEnums.length;
+
+ for (var key in {"toString": null}) {
+ hasDontEnumBug = false;
+ }
+
+ Object.keys = function keys(object) {
+
+ if (
+ (typeof object != "object" && typeof object != "function") ||
+ object === null
+ ) {
+ throw new TypeError("Object.keys called on a non-object");
+ }
+
+ var keys = [];
+ for (var name in object) {
+ if (owns(object, name)) {
+ keys.push(name);
+ }
+ }
+
+ if (hasDontEnumBug) {
+ for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
+ var dontEnum = dontEnums[i];
+ if (owns(object, dontEnum)) {
+ keys.push(dontEnum);
+ }
+ }
+ }
+ return keys;
+ };
+
+}
+if (!Date.now) {
+ Date.now = function now() {
+ return new Date().getTime();
+ };
+}
+if("0".split(void 0, 0).length) {
+ var string_split = String.prototype.split;
+ String.prototype.split = function(separator, limit) {
+ if(separator === void 0 && limit === 0)return [];
+ return string_split.apply(this, arguments);
+ }
+}
+if("".substr && "0b".substr(-1) !== "b") {
+ var string_substr = String.prototype.substr;
+ String.prototype.substr = function(start, length) {
+ return string_substr.call(
+ this,
+ start < 0 ? (start = this.length + start) < 0 ? 0 : start : start,
+ length
+ );
+ }
+}
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+ "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
+ "\u2029\uFEFF";
+if (!String.prototype.trim || ws.trim()) {
+ ws = "[" + ws + "]";
+ var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
+ trimEndRegexp = new RegExp(ws + ws + "*$");
+ String.prototype.trim = function trim() {
+ if (this === undefined || this === null) {
+ throw new TypeError("can't convert "+this+" to object");
+ }
+ return String(this)
+ .replace(trimBeginRegexp, "")
+ .replace(trimEndRegexp, "");
+ };
+}
+
+function toInteger(n) {
+ n = +n;
+ if (n !== n) { // isNaN
+ n = 0;
+ } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ return n;
+}
+
+function isPrimitive(input) {
+ var type = typeof input;
+ return (
+ input === null ||
+ type === "undefined" ||
+ type === "boolean" ||
+ type === "number" ||
+ type === "string"
+ );
+}
+
+function toPrimitive(input) {
+ var val, valueOf, toString;
+ if (isPrimitive(input)) {
+ return input;
+ }
+ valueOf = input.valueOf;
+ if (typeof valueOf === "function") {
+ val = valueOf.call(input);
+ if (isPrimitive(val)) {
+ return val;
+ }
+ }
+ toString = input.toString;
+ if (typeof toString === "function") {
+ val = toString.call(input);
+ if (isPrimitive(val)) {
+ return val;
+ }
+ }
+ throw new TypeError();
+}
+var toObject = function (o) {
+ if (o == null) { // this matches both null and undefined
+ throw new TypeError("can't convert "+o+" to object");
+ }
+ return Object(o);
+};
+
+});
+
+define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
+
+
+var EventEmitter = {};
+
+EventEmitter._emit =
+EventEmitter._dispatchEvent = function(eventName, e) {
+ this._eventRegistry = this._eventRegistry || {};
+ this._defaultHandlers = this._defaultHandlers || {};
+
+ var listeners = this._eventRegistry[eventName] || [];
+ var defaultHandler = this._defaultHandlers[eventName];
+ if (!listeners.length && !defaultHandler)
+ return;
+
+ if (typeof e != "object" || !e)
+ e = {};
+
+ if (!e.type)
+ e.type = eventName;
+
+ if (!e.stopPropagation) {
+ e.stopPropagation = function() {
+ this.propagationStopped = true;
+ };
+ }
+
+ if (!e.preventDefault) {
+ e.preventDefault = function() {
+ this.defaultPrevented = true;
+ };
+ }
+
+ for (var i=0; i<listeners.length; i++) {
+ listeners[i](e);
+ if (e.propagationStopped)
+ break;
+ }
+
+ if (defaultHandler && !e.defaultPrevented)
+ return defaultHandler(e);
+};
+
+EventEmitter.setDefaultHandler = function(eventName, callback) {
+ this._defaultHandlers = this._defaultHandlers || {};
+
+ if (this._defaultHandlers[eventName])
+ throw new Error("The default handler for '" + eventName + "' is already set");
+
+ this._defaultHandlers[eventName] = callback;
+};
+
+EventEmitter.on =
+EventEmitter.addEventListener = function(eventName, callback) {
+ this._eventRegistry = this._eventRegistry || {};
+
+ var listeners = this._eventRegistry[eventName];
+ if (!listeners)
+ listeners = this._eventRegistry[eventName] = [];
+
+ if (listeners.indexOf(callback) == -1)
+ listeners.push(callback);
+};
+
+EventEmitter.removeListener =
+EventEmitter.removeEventListener = function(eventName, callback) {
+ this._eventRegistry = this._eventRegistry || {};
+
+ var listeners = this._eventRegistry[eventName];
+ if (!listeners)
+ return;
+
+ var index = listeners.indexOf(callback);
+ if (index !== -1)
+ listeners.splice(index, 1);
+};
+
+EventEmitter.removeAllListeners = function(eventName) {
+ if (this._eventRegistry) this._eventRegistry[eventName] = [];
+};
+
+exports.EventEmitter = EventEmitter;
+
+});
+
+define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
+
+
+exports.inherits = (function() {
+ var tempCtor = function() {};
+ return function(ctor, superCtor) {
+ tempCtor.prototype = superCtor.prototype;
+ ctor.super_ = superCtor.prototype;
+ ctor.prototype = new tempCtor();
+ ctor.prototype.constructor = ctor;
+ };
+}());
+
+exports.mixin = function(obj, mixin) {
+ for (var key in mixin) {
+ obj[key] = mixin[key];
+ }
+};
+
+exports.implement = function(proto, mixin) {
+ exports.mixin(proto, mixin);
+};
+
+});
+
+define('ace/mode/css_worker', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/worker/mirror', 'ace/mode/css/csslint'], function(require, exports, module) {
+
+
+var oop = require("../lib/oop");
+var lang = require("../lib/lang");
+var Mirror = require("../worker/mirror").Mirror;
+var CSSLint = require("./css/csslint").CSSLint;
+
+var Worker = exports.Worker = function(sender) {
+ Mirror.call(this, sender);
+ this.setTimeout(400);
+ this.ruleset = null;
+ this.setDisabledRules("ids");
+ this.setInfoRules("adjoining-classes|qualified-headings|zero-units|gradients|import|outline-none");
+};
+
+oop.inherits(Worker, Mirror);
+
+(function() {
+ this.setInfoRules = function(ruleNames) {
+ if (typeof ruleNames == "string")
+ ruleNames = ruleNames.split("|");
+ this.infoRules = lang.arrayToMap(ruleNames);
+ this.doc.getValue() && this.deferredUpdate.schedule(100);
+ };
+
+ this.setDisabledRules = function(ruleNames) {
+ if (!ruleNames) {
+ this.ruleset = null;
+ } else {
+ if (typeof ruleNames == "string")
+ ruleNames = ruleNames.split("|");
+ var all = {};
+
+ CSSLint.getRules().forEach(function(x){
+ all[x.id] = true;
+ });
+ ruleNames.forEach(function(x) {
+ delete all[x];
+ });
+
+ this.ruleset = all;
+ }
+ this.doc.getValue() && this.deferredUpdate.schedule(100);
+ };
+
+ this.onUpdate = function() {
+ var value = this.doc.getValue();
+ var infoRules = this.infoRules;
+
+ var result = CSSLint.verify(value, this.ruleset);
+ this.sender.emit("csslint", result.messages.map(function(msg) {
+ return {
+ row: msg.line - 1,
+ column: msg.col - 1,
+ text: msg.message,
+ type: infoRules[msg.rule.id] ? "info" : msg.type
+ }
+ }));
+ };
+
+}).call(Worker.prototype);
+
+});
+
+define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
+
+
+exports.stringReverse = function(string) {
+ return string.split("").reverse().join("");
+};
+
+exports.stringRepeat = function (string, count) {
+ var result = '';
+ while (count > 0) {
+ if (count & 1)
+ result += string;
+
+ if (count >>= 1)
+ string += string;
+ }
+ return result;
+};
+
+var trimBeginRegexp = /^\s\s*/;
+var trimEndRegexp = /\s\s*$/;
+
+exports.stringTrimLeft = function (string) {
+ return string.replace(trimBeginRegexp, '');
+};
+
+exports.stringTrimRight = function (string) {
+ return string.replace(trimEndRegexp, '');
+};
+
+exports.copyObject = function(obj) {
+ var copy = {};
+ for (var key in obj) {
+ copy[key] = obj[key];
+ }
+ return copy;
+};
+
+exports.copyArray = function(array){
+ var copy = [];
+ for (var i=0, l=array.length; i<l; i++) {
+ if (array[i] && typeof array[i] == "object")
+ copy[i] = this.copyObject( array[i] );
+ else
+ copy[i] = array[i];
+ }
+ return copy;
+};
+
+exports.deepCopy = function (obj) {
+ if (typeof obj != "object") {
+ return obj;
+ }
+
+ var copy = obj.constructor();
+ for (var key in obj) {
+ if (typeof obj[key] == "object") {
+ copy[key] = this.deepCopy(obj[key]);
+ } else {
+ copy[key] = obj[key];
+ }
+ }
+ return copy;
+};
+
+exports.arrayToMap = function(arr) {
+ var map = {};
+ for (var i=0; i<arr.length; i++) {
+ map[arr[i]] = 1;
+ }
+ return map;
+
+};
+
+exports.createMap = function(props) {
+ var map = Object.create(null);
+ for (var i in props) {
+ map[i] = props[i];
+ }
+ return map;
+};
+exports.arrayRemove = function(array, value) {
+ for (var i = 0; i <= array.length; i++) {
+ if (value === array[i]) {
+ array.splice(i, 1);
+ }
+ }
+};
+
+exports.escapeRegExp = function(str) {
+ return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
+};
+
+exports.escapeHTML = function(str) {
+ return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
+};
+
+exports.getMatchOffsets = function(string, regExp) {
+ var matches = [];
+
+ string.replace(regExp, function(str) {
+ matches.push({
+ offset: arguments[arguments.length-2],
+ length: str.length
+ });
+ });
+
+ return matches;
+};
+exports.deferredCall = function(fcn) {
+
+ var timer = null;
+ var callback = function() {
+ timer = null;
+ fcn();
+ };
+
+ var deferred = function(timeout) {
+ deferred.cancel();
+ timer = setTimeout(callback, timeout || 0);
+ return deferred;
+ };
+
+ deferred.schedule = deferred;
+
+ deferred.call = function() {
+ this.cancel();
+ fcn();
+ return deferred;
+ };
+
+ deferred.cancel = function() {
+ clearTimeout(timer);
+ timer = null;
+ return deferred;
+ };
+
+ return deferred;
+};
+
+
+exports.delayedCall = function(fcn, defaultTimeout) {
+ var timer = null;
+ var callback = function() {
+ timer = null;
+ fcn();
+ };
+
+ var _self = function(timeout) {
+ timer && clearTimeout(timer);
+ timer = setTimeout(callback, timeout || defaultTimeout);
+ };
+
+ _self.delay = _self;
+ _self.schedule = function(timeout) {
+ if (timer == null)
+ timer = setTimeout(callback, timeout || 0);
+ };
+
+ _self.call = function() {
+ this.cancel();
+ fcn();
+ };
+
+ _self.cancel = function() {
+ timer && clearTimeout(timer);
+ timer = null;
+ };
+
+ _self.isPending = function() {
+ return timer;
+ };
+
+ return _self;
+};
+});
+define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
+
+
+var Document = require("../document").Document;
+var lang = require("../lib/lang");
+
+var Mirror = exports.Mirror = function(sender) {
+ this.sender = sender;
+ var doc = this.doc = new Document("");
+
+ var deferredUpdate = this.deferredUpdate = lang.deferredCall(this.onUpdate.bind(this));
+
+ var _self = this;
+ sender.on("change", function(e) {
+ doc.applyDeltas([e.data]);
+ deferredUpdate.schedule(_self.$timeout);
+ });
+};
+
+(function() {
+
+ this.$timeout = 500;
+
+ this.setTimeout = function(timeout) {
+ this.$timeout = timeout;
+ };
+
+ this.setValue = function(value) {
+ this.doc.setValue(value);
+ this.deferredUpdate.schedule(this.$timeout);
+ };
+
+ this.getValue = function(callbackId) {
+ this.sender.callback(this.doc.getValue(), callbackId);
+ };
+
+ this.onUpdate = function() {
+ };
+
+}).call(Mirror.prototype);
+
+});
+
+define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
+
+
+var oop = require("./lib/oop");
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+var Range = require("./range").Range;
+var Anchor = require("./anchor").Anchor;
+
+var Document = function(text) {
+ this.$lines = [];
+ if (text.length == 0) {
+ this.$lines = [""];
+ } else if (Array.isArray(text)) {
+ this.insertLines(0, text);
+ } else {
+ this.insert({row: 0, column:0}, text);
+ }
+};
+
+(function() {
+
+ oop.implement(this, EventEmitter);
+ this.setValue = function(text) {
+ var len = this.getLength();
+ this.remove(new Range(0, 0, len, this.getLine(len-1).length));
+ this.insert({row: 0, column:0}, text);
+ };
+ this.getValue = function() {
+ return this.getAllLines().join(this.getNewLineCharacter());
+ };
+ this.createAnchor = function(row, column) {
+ return new Anchor(this, row, column);
+ };
+ if ("aaa".split(/a/).length == 0)
+ this.$split = function(text) {
+ return text.replace(/\r\n|\r/g, "\n").split("\n");
+ }
+ else
+ this.$split = function(text) {
+ return text.split(/\r\n|\r|\n/);
+ };
+
+
+
+ this.$detectNewLine = function(text) {
+ var match = text.match(/^.*?(\r\n|\r|\n)/m);
+ if (match) {
+ this.$autoNewLine = match[1];
+ } else {
+ this.$autoNewLine = "\n";
+ }
+ };
+ this.getNewLineCharacter = function() {
+ switch (this.$newLineMode) {
+ case "windows":
+ return "\r\n";
+
+ case "unix":
+ return "\n";
+
+ default:
+ return this.$autoNewLine;
+ }
+ };
+
+ this.$autoNewLine = "\n";
+ this.$newLineMode = "auto";
+ this.setNewLineMode = function(newLineMode) {
+ if (this.$newLineMode === newLineMode)
+ return;
+
+ this.$newLineMode = newLineMode;
+ };
+ this.getNewLineMode = function() {
+ return this.$newLineMode;
+ };
+ this.isNewLine = function(text) {
+ return (text == "\r\n" || text == "\r" || text == "\n");
+ };
+ this.getLine = function(row) {
+ return this.$lines[row] || "";
+ };
+ this.getLines = function(firstRow, lastRow) {
+ return this.$lines.slice(firstRow, lastRow + 1);
+ };
+ this.getAllLines = function() {
+ return this.getLines(0, this.getLength());
+ };
+ this.getLength = function() {
+ return this.$lines.length;
+ };
+ this.getTextRange = function(range) {
+ if (range.start.row == range.end.row) {
+ return this.$lines[range.start.row].substring(range.start.column,
+ range.end.column);
+ }
+ else {
+ var lines = this.getLines(range.start.row+1, range.end.row-1);
+ lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
+ lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
+ return lines.join(this.getNewLineCharacter());
+ }
+ };
+
+ this.$clipPosition = function(position) {
+ var length = this.getLength();
+ if (position.row >= length) {
+ position.row = Math.max(0, length - 1);
+ position.column = this.getLine(length-1).length;
+ }
+ return position;
+ };
+ this.insert = function(position, text) {
+ if (!text || text.length === 0)
+ return position;
+
+ position = this.$clipPosition(position);
+ if (this.getLength() <= 1)
+ this.$detectNewLine(text);
+
+ var lines = this.$split(text);
+ var firstLine = lines.splice(0, 1)[0];
+ var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0];
+
+ position = this.insertInLine(position, firstLine);
+ if (lastLine !== null) {
+ position = this.insertNewLine(position); // terminate first line
+ position = this.insertLines(position.row, lines);
+ position = this.insertInLine(position, lastLine || "");
+ }
+ return position;
+ };
+ this.insertLines = function(row, lines) {
+ if (lines.length == 0)
+ return {row: row, column: 0};
+ if (lines.length > 0xFFFF) {
+ var end = this.insertLines(row, lines.slice(0xFFFF));
+ lines = lines.slice(0, 0xFFFF);
+ }
+
+ var args = [row, 0];
+ args.push.apply(args, lines);
+ this.$lines.splice.apply(this.$lines, args);
+
+ var range = new Range(row, 0, row + lines.length, 0);
+ var delta = {
+ action: "insertLines",
+ range: range,
+ lines: lines
+ };
+ this._emit("change", { data: delta });
+ return end || range.end;
+ };
+ this.insertNewLine = function(position) {
+ position = this.$clipPosition(position);
+ var line = this.$lines[position.row] || "";
+
+ this.$lines[position.row] = line.substring(0, position.column);
+ this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
+
+ var end = {
+ row : position.row + 1,
+ column : 0
+ };
+
+ var delta = {
+ action: "insertText",
+ range: Range.fromPoints(position, end),
+ text: this.getNewLineCharacter()
+ };
+ this._emit("change", { data: delta });
+
+ return end;
+ };
+ this.insertInLine = function(position, text) {
+ if (text.length == 0)
+ return position;
+
+ var line = this.$lines[position.row] || "";
+
+ this.$lines[position.row] = line.substring(0, position.column) + text
+ + line.substring(position.column);
+
+ var end = {
+ row : position.row,
+ column : position.column + text.length
+ };
+
+ var delta = {
+ action: "insertText",
+ range: Range.fromPoints(position, end),
+ text: text
+ };
+ this._emit("change", { data: delta });
+
+ return end;
+ };
+ this.remove = function(range) {
+ range.start = this.$clipPosition(range.start);
+ range.end = this.$clipPosition(range.end);
+
+ if (range.isEmpty())
+ return range.start;
+
+ var firstRow = range.start.row;
+ var lastRow = range.end.row;
+
+ if (range.isMultiLine()) {
+ var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1;
+ var lastFullRow = lastRow - 1;
+
+ if (range.end.column > 0)
+ this.removeInLine(lastRow, 0, range.end.column);
+
+ if (lastFullRow >= firstFullRow)
+ this.removeLines(firstFullRow, lastFullRow);
+
+ if (firstFullRow != firstRow) {
+ this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
+ this.removeNewLine(range.start.row);
+ }
+ }
+ else {
+ this.removeInLine(firstRow, range.start.column, range.end.column);
+ }
+ return range.start;
+ };
+ this.removeInLine = function(row, startColumn, endColumn) {
+ if (startColumn == endColumn)
+ return;
+
+ var range = new Range(row, startColumn, row, endColumn);
+ var line = this.getLine(row);
+ var removed = line.substring(startColumn, endColumn);
+ var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
+ this.$lines.splice(row, 1, newLine);
+
+ var delta = {
+ action: "removeText",
+ range: range,
+ text: removed
+ };
+ this._emit("change", { data: delta });
+ return range.start;
+ };
+ this.removeLines = function(firstRow, lastRow) {
+ var range = new Range(firstRow, 0, lastRow + 1, 0);
+ var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
+
+ var delta = {
+ action: "removeLines",
+ range: range,
+ nl: this.getNewLineCharacter(),
+ lines: removed
+ };
+ this._emit("change", { data: delta });
+ return removed;
+ };
+ this.removeNewLine = function(row) {
+ var firstLine = this.getLine(row);
+ var secondLine = this.getLine(row+1);
+
+ var range = new Range(row, firstLine.length, row+1, 0);
+ var line = firstLine + secondLine;
+
+ this.$lines.splice(row, 2, line);
+
+ var delta = {
+ action: "removeText",
+ range: range,
+ text: this.getNewLineCharacter()
+ };
+ this._emit("change", { data: delta });
+ };
+ this.replace = function(range, text) {
+ if (text.length == 0 && range.isEmpty())
+ return range.start;
+ if (text == this.getTextRange(range))
+ return range.end;
+
+ this.remove(range);
+ if (text) {
+ var end = this.insert(range.start, text);
+ }
+ else {
+ end = range.start;
+ }
+
+ return end;
+ };
+ this.applyDeltas = function(deltas) {
+ for (var i=0; i<deltas.length; i++) {
+ var delta = deltas[i];
+ var range = Range.fromPoints(delta.range.start, delta.range.end);
+
+ if (delta.action == "insertLines")
+ this.insertLines(range.start.row, delta.lines);
+ else if (delta.action == "insertText")
+ this.insert(range.start, delta.text);
+ else if (delta.action == "removeLines")
+ this.removeLines(range.start.row, range.end.row - 1);
+ else if (delta.action == "removeText")
+ this.remove(range);
+ }
+ };
+ this.revertDeltas = function(deltas) {
+ for (var i=deltas.length-1; i>=0; i--) {
+ var delta = deltas[i];
+
+ var range = Range.fromPoints(delta.range.start, delta.range.end);
+
+ if (delta.action == "insertLines")
+ this.removeLines(range.start.row, range.end.row - 1);
+ else if (delta.action == "insertText")
+ this.remove(range);
+ else if (delta.action == "removeLines")
+ this.insertLines(range.start.row, delta.lines);
+ else if (delta.action == "removeText")
+ this.insert(range.start, delta.text);
+ }
+ };
+ this.indexToPosition = function(index, startRow) {
+ var lines = this.$lines || this.getAllLines();
+ var newlineLength = this.getNewLineCharacter().length;
+ for (var i = startRow || 0, l = lines.length; i < l; i++) {
+ index -= lines[i].length + newlineLength;
+ if (index < 0)
+ return {row: i, column: index + lines[i].length + newlineLength};
+ }
+ return {row: l-1, column: lines[l-1].length};
+ };
+ this.positionToIndex = function(pos, startRow) {
+ var lines = this.$lines || this.getAllLines();
+ var newlineLength = this.getNewLineCharacter().length;
+ var index = 0;
+ var row = Math.min(pos.row, lines.length);
+ for (var i = startRow || 0; i < row; ++i)
+ index += lines[i].length;
+
+ return index + newlineLength * i + pos.column;
+ };
+
+}).call(Document.prototype);
+
+exports.Document = Document;
+});
+
+define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
+var Range = function(startRow, startColumn, endRow, endColumn) {
+ this.start = {
+ row: startRow,
+ column: startColumn
+ };
+
+ this.end = {
+ row: endRow,
+ column: endColumn
+ };
+};
+
+(function() {
+ this.isEqual = function(range) {
+ return this.start.row == range.start.row &&
+ this.end.row == range.end.row &&
+ this.start.column == range.start.column &&
+ this.end.column == range.end.column
+ };
+ this.toString = function() {
+ return ("Range: [" + this.start.row + "/" + this.start.column +
+ "] -> [" + this.end.row + "/" + this.end.column + "]");
+ };
+
+ this.contains = function(row, column) {
+ return this.compare(row, column) == 0;
+ };
+ this.compareRange = function(range) {
+ var cmp,
+ end = range.end,
+ start = range.start;
+
+ cmp = this.compare(end.row, end.column);
+ if (cmp == 1) {
+ cmp = this.compare(start.row, start.column);
+ if (cmp == 1) {
+ return 2;
+ } else if (cmp == 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else if (cmp == -1) {
+ return -2;
+ } else {
+ cmp = this.compare(start.row, start.column);
+ if (cmp == -1) {
+ return -1;
+ } else if (cmp == 1) {
+ return 42;
+ } else {
+ return 0;
+ }
+ }
+ };
+ this.comparePoint = function(p) {
+ return this.compare(p.row, p.column);
+ };
+ this.containsRange = function(range) {
+ return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
+ };
+ this.intersects = function(range) {
+ var cmp = this.compareRange(range);
+ return (cmp == -1 || cmp == 0 || cmp == 1);
+ };
+ this.isEnd = function(row, column) {
+ return this.end.row == row && this.end.column == column;
+ };
+ this.isStart = function(row, column) {
+ return this.start.row == row && this.start.column == column;
+ };
+ this.setStart = function(row, column) {
+ if (typeof row == "object") {
+ this.start.column = row.column;
+ this.start.row = row.row;
+ } else {
+ this.start.row = row;
+ this.start.column = column;
+ }
+ };
+ this.setEnd = function(row, column) {
+ if (typeof row == "object") {
+ this.end.column = row.column;
+ this.end.row = row.row;
+ } else {
+ this.end.row = row;
+ this.end.column = column;
+ }
+ };
+ this.inside = function(row, column) {
+ if (this.compare(row, column) == 0) {
+ if (this.isEnd(row, column) || this.isStart(row, column)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ return false;
+ };
+ this.insideStart = function(row, column) {
+ if (this.compare(row, column) == 0) {
+ if (this.isEnd(row, column)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ return false;
+ };
+ this.insideEnd = function(row, column) {
+ if (this.compare(row, column) == 0) {
+ if (this.isStart(row, column)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ return false;
+ };
+ this.compare = function(row, column) {
+ if (!this.isMultiLine()) {
+ if (row === this.start.row) {
+ return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
+ };
+ }
+
+ if (row < this.start.row)
+ return -1;
+
+ if (row > this.end.row)
+ return 1;
+
+ if (this.start.row === row)
+ return column >= this.start.column ? 0 : -1;
+
+ if (this.end.row === row)
+ return column <= this.end.column ? 0 : 1;
+
+ return 0;
+ };
+ this.compareStart = function(row, column) {
+ if (this.start.row == row && this.start.column == column) {
+ return -1;
+ } else {
+ return this.compare(row, column);
+ }
+ };
+ this.compareEnd = function(row, column) {
+ if (this.end.row == row && this.end.column == column) {
+ return 1;
+ } else {
+ return this.compare(row, column);
+ }
+ };
+ this.compareInside = function(row, column) {
+ if (this.end.row == row && this.end.column == column) {
+ return 1;
+ } else if (this.start.row == row && this.start.column == column) {
+ return -1;
+ } else {
+ return this.compare(row, column);
+ }
+ };
+ this.clipRows = function(firstRow, lastRow) {
+ if (this.end.row > lastRow) {
+ var end = {
+ row: lastRow+1,
+ column: 0
+ };
+ }
+
+ if (this.start.row > lastRow) {
+ var start = {
+ row: lastRow+1,
+ column: 0
+ };
+ }
+
+ if (this.start.row < firstRow) {
+ var start = {
+ row: firstRow,
+ column: 0
+ };
+ }
+
+ if (this.end.row < firstRow) {
+ var end = {
+ row: firstRow,
+ column: 0
+ };
+ }
+ return Range.fromPoints(start || this.start, end || this.end);
+ };
+ this.extend = function(row, column) {
+ var cmp = this.compare(row, column);
+
+ if (cmp == 0)
+ return this;
+ else if (cmp == -1)
+ var start = {row: row, column: column};
+ else
+ var end = {row: row, column: column};
+
+ return Range.fromPoints(start || this.start, end || this.end);
+ };
+
+ this.isEmpty = function() {
+ return (this.start.row == this.end.row && this.start.column == this.end.column);
+ };
+ this.isMultiLine = function() {
+ return (this.start.row !== this.end.row);
+ };
+ this.clone = function() {
+ return Range.fromPoints(this.start, this.end);
+ };
+ this.collapseRows = function() {
+ if (this.end.column == 0)
+ return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
+ else
+ return new Range(this.start.row, 0, this.end.row, 0)
+ };
+ this.toScreenRange = function(session) {
+ var screenPosStart =
+ session.documentToScreenPosition(this.start);
+ var screenPosEnd =
+ session.documentToScreenPosition(this.end);
+
+ return new Range(
+ screenPosStart.row, screenPosStart.column,
+ screenPosEnd.row, screenPosEnd.column
+ );
+ };
+
+}).call(Range.prototype);
+Range.fromPoints = function(start, end) {
+ return new Range(start.row, start.column, end.row, end.column);
+};
+
+exports.Range = Range;
+});
+
+define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
+
+
+var oop = require("./lib/oop");
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+
+var Anchor = exports.Anchor = function(doc, row, column) {
+ this.document = doc;
+
+ if (typeof column == "undefined")
+ this.setPosition(row.row, row.column);
+ else
+ this.setPosition(row, column);
+
+ this.$onChange = this.onChange.bind(this);
+ doc.on("change", this.$onChange);
+};
+
+(function() {
+
+ oop.implement(this, EventEmitter);
+
+ this.getPosition = function() {
+ return this.$clipPositionToDocument(this.row, this.column);
+ };
+
+ this.getDocument = function() {
+ return this.document;
+ };
+
+ this.onChange = function(e) {
+ var delta = e.data;
+ var range = delta.range;
+
+ if (range.start.row == range.end.row && range.start.row != this.row)
+ return;
+
+ if (range.start.row > this.row)
+ return;
+
+ if (range.start.row == this.row && range.start.column > this.column)
+ return;
+
+ var row = this.row;
+ var column = this.column;
+
+ if (delta.action === "insertText") {
+ if (range.start.row === row && range.start.column <= column) {
+ if (range.start.row === range.end.row) {
+ column += range.end.column - range.start.column;
+ }
+ else {
+ column -= range.start.column;
+ row += range.end.row - range.start.row;
+ }
+ }
+ else if (range.start.row !== range.end.row && range.start.row < row) {
+ row += range.end.row - range.start.row;
+ }
+ } else if (delta.action === "insertLines") {
+ if (range.start.row <= row) {
+ row += range.end.row - range.start.row;
+ }
+ }
+ else if (delta.action == "removeText") {
+ if (range.start.row == row && range.start.column < column) {
+ if (range.end.column >= column)
+ column = range.start.column;
+ else
+ column = Math.max(0, column - (range.end.column - range.start.column));
+
+ } else if (range.start.row !== range.end.row && range.start.row < row) {
+ if (range.end.row == row) {
+ column = Math.max(0, column - range.end.column) + range.start.column;
+ }
+ row -= (range.end.row - range.start.row);
+ }
+ else if (range.end.row == row) {
+ row -= range.end.row - range.start.row;
+ column = Math.max(0, column - range.end.column) + range.start.column;
+ }
+ } else if (delta.action == "removeLines") {
+ if (range.start.row <= row) {
+ if (range.end.row <= row)
+ row -= range.end.row - range.start.row;
+ else {
+ row = range.start.row;
+ column = 0;
+ }
+ }
+ }
+
+ this.setPosition(row, column, true);
+ };
+
+ this.setPosition = function(row, column, noClip) {
+ var pos;
+ if (noClip) {
+ pos = {
+ row: row,
+ column: column
+ };
+ }
+ else {
+ pos = this.$clipPositionToDocument(row, column);
+ }
+
+ if (this.row == pos.row && this.column == pos.column)
+ return;
+
+ var old = {
+ row: this.row,
+ column: this.column
+ };
+
+ this.row = pos.row;
+ this.column = pos.column;
+ this._emit("change", {
+ old: old,
+ value: pos
+ });
+ };
+
+ this.detach = function() {
+ this.document.removeEventListener("change", this.$onChange);
+ };
+ this.$clipPositionToDocument = function(row, column) {
+ var pos = {};
+
+ if (row >= this.document.getLength()) {
+ pos.row = Math.max(0, this.document.getLength() - 1);
+ pos.column = this.document.getLine(pos.row).length;
+ }
+ else if (row < 0) {
+ pos.row = 0;
+ pos.column = 0;
+ }
+ else {
+ pos.row = row;
+ pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
+ }
+
+ if (column < 0)
+ pos.column = 0;
+
+ return pos;
+ };
+
+}).call(Anchor.prototype);
+
+});
+define('ace/mode/css/csslint', ['require', 'exports', 'module' ], function(require, exports, module) {
+var parserlib = {};
+(function(){
+function EventTarget(){
+ this._listeners = {};
+}
+
+EventTarget.prototype = {
+ constructor: EventTarget,
+ addListener: function(type, listener){
+ if (!this._listeners[type]){
+ this._listeners[type] = [];
+ }
+
+ this._listeners[type].push(listener);
+ },
+ fire: function(event){
+ if (typeof event == "string"){
+ event = { type: event };
+ }
+ if (typeof event.target != "undefined"){
+ event.target = this;
+ }
+
+ if (typeof event.type == "undefined"){
+ throw new Error("Event object missing 'type' property.");
+ }
+
+ if (this._listeners[event.type]){
+ var listeners = this._listeners[event.type].concat();
+ for (var i=0, len=listeners.length; i < len; i++){
+ listeners[i].call(this, event);
+ }
+ }
+ },
+ removeListener: function(type, listener){
+ if (this._listeners[type]){
+ var listeners = this._listeners[type];
+ for (var i=0, len=listeners.length; i < len; i++){
+ if (listeners[i] === listener){
+ listeners.splice(i, 1);
+ break;
+ }
+ }
+
+
+ }
+ }
+};
+function StringReader(text){
+ this._input = text.replace(/\n\r?/g, "\n");
+ this._line = 1;
+ this._col = 1;
+ this._cursor = 0;
+}
+
+StringReader.prototype = {
+ constructor: StringReader,
+ getCol: function(){
+ return this._col;
+ },
+ getLine: function(){
+ return this._line ;
+ },
+ eof: function(){
+ return (this._cursor == this._input.length);
+ },
+ peek: function(count){
+ var c = null;
+ count = (typeof count == "undefined" ? 1 : count);
+ if (this._cursor < this._input.length){
+ c = this._input.charAt(this._cursor + count - 1);
+ }
+
+ return c;
+ },
+ read: function(){
+ var c = null;
+ if (this._cursor < this._input.length){
+ if (this._input.charAt(this._cursor) == "\n"){
+ this._line++;
+ this._col=1;
+ } else {
+ this._col++;
+ }
+ c = this._input.charAt(this._cursor++);
+ }
+
+ return c;
+ },
+ mark: function(){
+ this._bookmark = {
+ cursor: this._cursor,
+ line: this._line,
+ col: this._col
+ };
+ },
+
+ reset: function(){
+ if (this._bookmark){
+ this._cursor = this._bookmark.cursor;
+ this._line = this._bookmark.line;
+ this._col = this._bookmark.col;
+ delete this._bookmark;
+ }
+ },
+ readTo: function(pattern){
+
+ var buffer = "",
+ c;
+ while (buffer.length < pattern.length || buffer.lastIndexOf(pattern) != buffer.length - pattern.length){
+ c = this.read();
+ if (c){
+ buffer += c;
+ } else {
+ throw new Error("Expected \"" + pattern + "\" at line " + this._line + ", col " + this._col + ".");
+ }
+ }
+
+ return buffer;
+
+ },
+ readWhile: function(filter){
+
+ var buffer = "",
+ c = this.read();
+
+ while(c !== null && filter(c)){
+ buffer += c;
+ c = this.read();
+ }
+
+ return buffer;
+
+ },
+ readMatch: function(matcher){
+
+ var source = this._input.substring(this._cursor),
+ value = null;
+ if (typeof matcher == "string"){
+ if (source.indexOf(matcher) === 0){
+ value = this.readCount(matcher.length);
+ }
+ } else if (matcher instanceof RegExp){
+ if (matcher.test(source)){
+ value = this.readCount(RegExp.lastMatch.length);
+ }
+ }
+
+ return value;
+ },
+ readCount: function(count){
+ var buffer = "";
+
+ while(count--){
+ buffer += this.read();
+ }
+
+ return buffer;
+ }
+
+};
+function SyntaxError(message, line, col){
+ this.col = col;
+ this.line = line;
+ this.message = message;
+
+}
+SyntaxError.prototype = new Error();
+function SyntaxUnit(text, line, col, type){
+ this.col = col;
+ this.line = line;
+ this.text = text;
+ this.type = type;
+}
+SyntaxUnit.fromToken = function(token){
+ return new SyntaxUnit(token.value, token.startLine, token.startCol);
+};
+
+SyntaxUnit.prototype = {
+ constructor: SyntaxUnit,
+ valueOf: function(){
+ return this.toString();
+ },
+ toString: function(){
+ return this.text;
+ }
+
+};
+function TokenStreamBase(input, tokenData){
+ this._reader = input ? new StringReader(input.toString()) : null;
+ this._token = null;
+ this._tokenData = tokenData;
+ this._lt = [];
+ this._ltIndex = 0;
+
+ this._ltIndexCache = [];
+}
+TokenStreamBase.createTokenData = function(tokens){
+
+ var nameMap = [],
+ typeMap = {},
+ tokenData = tokens.concat([]),
+ i = 0,
+ len = tokenData.length+1;
+
+ tokenData.UNKNOWN = -1;
+ tokenData.unshift({name:"EOF"});
+
+ for (; i < len; i++){
+ nameMap.push(tokenData[i].name);
+ tokenData[tokenData[i].name] = i;
+ if (tokenData[i].text){
+ typeMap[tokenData[i].text] = i;
+ }
+ }
+
+ tokenData.name = function(tt){
+ return nameMap[tt];
+ };
+
+ tokenData.type = function(c){
+ return typeMap[c];
+ };
+
+ return tokenData;
+};
+
+TokenStreamBase.prototype = {
+ constructor: TokenStreamBase,
+ match: function(tokenTypes, channel){
+ if (!(tokenTypes instanceof Array)){
+ tokenTypes = [tokenTypes];
+ }
+
+ var tt = this.get(channel),
+ i = 0,
+ len = tokenTypes.length;
+
+ while(i < len){
+ if (tt == tokenTypes[i++]){
+ return true;
+ }
+ }
+ this.unget();
+ return false;
+ },
+ mustMatch: function(tokenTypes, channel){
+
+ var token;
+ if (!(tokenTypes instanceof Array)){
+ tokenTypes = [tokenTypes];
+ }
+
+ if (!this.match.apply(this, arguments)){
+ token = this.LT(1);
+ throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name +
+ " at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
+ }
+ },
+ advance: function(tokenTypes, channel){
+
+ while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){
+ this.get();
+ }
+
+ return this.LA(0);
+ },
+ get: function(channel){
+
+ var tokenInfo = this._tokenData,
+ reader = this._reader,
+ value,
+ i =0,
+ len = tokenInfo.length,
+ found = false,
+ token,
+ info;
+ if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){
+
+ i++;
+ this._token = this._lt[this._ltIndex++];
+ info = tokenInfo[this._token.type];
+ while((info.channel !== undefined && channel !== info.channel) &&
+ this._ltIndex < this._lt.length){
+ this._token = this._lt[this._ltIndex++];
+ info = tokenInfo[this._token.type];
+ i++;
+ }
+ if ((info.channel === undefined || channel === info.channel) &&
+ this._ltIndex <= this._lt.length){
+ this._ltIndexCache.push(i);
+ return this._token.type;
+ }
+ }
+ token = this._getToken();
+ if (token.type > -1 && !tokenInfo[token.type].hide){
+ token.channel = tokenInfo[token.type].channel;
+ this._token = token;
+ this._lt.push(token);
+ this._ltIndexCache.push(this._lt.length - this._ltIndex + i);
+ if (this._lt.length > 5){
+ this._lt.shift();
+ }
+ if (this._ltIndexCache.length > 5){
+ this._ltIndexCache.shift();
+ }
+ this._ltIndex = this._lt.length;
+ }
+ info = tokenInfo[token.type];
+ if (info &&
+ (info.hide ||
+ (info.channel !== undefined && channel !== info.channel))){
+ return this.get(channel);
+ } else {
+ return token.type;
+ }
+ },
+ LA: function(index){
+ var total = index,
+ tt;
+ if (index > 0){
+ if (index > 5){
+ throw new Error("Too much lookahead.");
+ }
+ while(total){
+ tt = this.get();
+ total--;
+ }
+ while(total < index){
+ this.unget();
+ total++;
+ }
+ } else if (index < 0){
+
+ if(this._lt[this._ltIndex+index]){
+ tt = this._lt[this._ltIndex+index].type;
+ } else {
+ throw new Error("Too much lookbehind.");
+ }
+
+ } else {
+ tt = this._token.type;
+ }
+
+ return tt;
+
+ },
+ LT: function(index){
+ this.LA(index);
+ return this._lt[this._ltIndex+index-1];
+ },
+ peek: function(){
+ return this.LA(1);
+ },
+ token: function(){
+ return this._token;
+ },
+ tokenName: function(tokenType){
+ if (tokenType < 0 || tokenType > this._tokenData.length){
+ return "UNKNOWN_TOKEN";
+ } else {
+ return this._tokenData[tokenType].name;
+ }
+ },
+ tokenType: function(tokenName){
+ return this._tokenData[tokenName] || -1;
+ },
+ unget: function(){
+ if (this._ltIndexCache.length){
+ this._ltIndex -= this._ltIndexCache.pop();//--;
+ this._token = this._lt[this._ltIndex - 1];
+ } else {
+ throw new Error("Too much lookahead.");
+ }
+ }
+
+};
+
+
+
+
+parserlib.util = {
+StringReader: StringReader,
+SyntaxError : SyntaxError,
+SyntaxUnit : SyntaxUnit,
+EventTarget : EventTarget,
+TokenStreamBase : TokenStreamBase
+};
+})();
+(function(){
+var EventTarget = parserlib.util.EventTarget,
+TokenStreamBase = parserlib.util.TokenStreamBase,
+StringReader = parserlib.util.StringReader,
+SyntaxError = parserlib.util.SyntaxError,
+SyntaxUnit = parserlib.util.SyntaxUnit;
+
+
+var Colors = {
+ aliceblue :"#f0f8ff",
+ antiquewhite :"#faebd7",
+ aqua :"#00ffff",
+ aquamarine :"#7fffd4",
+ azure :"#f0ffff",
+ beige :"#f5f5dc",
+ bisque :"#ffe4c4",
+ black :"#000000",
+ blanchedalmond :"#ffebcd",
+ blue :"#0000ff",
+ blueviolet :"#8a2be2",
+ brown :"#a52a2a",
+ burlywood :"#deb887",
+ cadetblue :"#5f9ea0",
+ chartreuse :"#7fff00",
+ chocolate :"#d2691e",
+ coral :"#ff7f50",
+ cornflowerblue :"#6495ed",
+ cornsilk :"#fff8dc",
+ crimson :"#dc143c",
+ cyan :"#00ffff",
+ darkblue :"#00008b",
+ darkcyan :"#008b8b",
+ darkgoldenrod :"#b8860b",
+ darkgray :"#a9a9a9",
+ darkgreen :"#006400",
+ darkkhaki :"#bdb76b",
+ darkmagenta :"#8b008b",
+ darkolivegreen :"#556b2f",
+ darkorange :"#ff8c00",
+ darkorchid :"#9932cc",
+ darkred :"#8b0000",
+ darksalmon :"#e9967a",
+ darkseagreen :"#8fbc8f",
+ darkslateblue :"#483d8b",
+ darkslategray :"#2f4f4f",
+ darkturquoise :"#00ced1",
+ darkviolet :"#9400d3",
+ deeppink :"#ff1493",
+ deepskyblue :"#00bfff",
+ dimgray :"#696969",
+ dodgerblue :"#1e90ff",
+ firebrick :"#b22222",
+ floralwhite :"#fffaf0",
+ forestgreen :"#228b22",
+ fuchsia :"#ff00ff",
+ gainsboro :"#dcdcdc",
+ ghostwhite :"#f8f8ff",
+ gold :"#ffd700",
+ goldenrod :"#daa520",
+ gray :"#808080",
+ green :"#008000",
+ greenyellow :"#adff2f",
+ honeydew :"#f0fff0",
+ hotpink :"#ff69b4",
+ indianred :"#cd5c5c",
+ indigo :"#4b0082",
+ ivory :"#fffff0",
+ khaki :"#f0e68c",
+ lavender :"#e6e6fa",
+ lavenderblush :"#fff0f5",
+ lawngreen :"#7cfc00",
+ lemonchiffon :"#fffacd",
+ lightblue :"#add8e6",
+ lightcoral :"#f08080",
+ lightcyan :"#e0ffff",
+ lightgoldenrodyellow :"#fafad2",
+ lightgray :"#d3d3d3",
+ lightgreen :"#90ee90",
+ lightpink :"#ffb6c1",
+ lightsalmon :"#ffa07a",
+ lightseagreen :"#20b2aa",
+ lightskyblue :"#87cefa",
+ lightslategray :"#778899",
+ lightsteelblue :"#b0c4de",
+ lightyellow :"#ffffe0",
+ lime :"#00ff00",
+ limegreen :"#32cd32",
+ linen :"#faf0e6",
+ magenta :"#ff00ff",
+ maroon :"#800000",
+ mediumaquamarine:"#66cdaa",
+ mediumblue :"#0000cd",
+ mediumorchid :"#ba55d3",
+ mediumpurple :"#9370d8",
+ mediumseagreen :"#3cb371",
+ mediumslateblue :"#7b68ee",
+ mediumspringgreen :"#00fa9a",
+ mediumturquoise :"#48d1cc",
+ mediumvioletred :"#c71585",
+ midnightblue :"#191970",
+ mintcream :"#f5fffa",
+ mistyrose :"#ffe4e1",
+ moccasin :"#ffe4b5",
+ navajowhite :"#ffdead",
+ navy :"#000080",
+ oldlace :"#fdf5e6",
+ olive :"#808000",
+ olivedrab :"#6b8e23",
+ orange :"#ffa500",
+ orangered :"#ff4500",
+ orchid :"#da70d6",
+ palegoldenrod :"#eee8aa",
+ palegreen :"#98fb98",
+ paleturquoise :"#afeeee",
+ palevioletred :"#d87093",
+ papayawhip :"#ffefd5",
+ peachpuff :"#ffdab9",
+ peru :"#cd853f",
+ pink :"#ffc0cb",
+ plum :"#dda0dd",
+ powderblue :"#b0e0e6",
+ purple :"#800080",
+ red :"#ff0000",
+ rosybrown :"#bc8f8f",
+ royalblue :"#4169e1",
+ saddlebrown :"#8b4513",
+ salmon :"#fa8072",
+ sandybrown :"#f4a460",
+ seagreen :"#2e8b57",
+ seashell :"#fff5ee",
+ sienna :"#a0522d",
+ silver :"#c0c0c0",
+ skyblue :"#87ceeb",
+ slateblue :"#6a5acd",
+ slategray :"#708090",
+ snow :"#fffafa",
+ springgreen :"#00ff7f",
+ steelblue :"#4682b4",
+ tan :"#d2b48c",
+ teal :"#008080",
+ thistle :"#d8bfd8",
+ tomato :"#ff6347",
+ turquoise :"#40e0d0",
+ violet :"#ee82ee",
+ wheat :"#f5deb3",
+ white :"#ffffff",
+ whitesmoke :"#f5f5f5",
+ yellow :"#ffff00",
+ yellowgreen :"#9acd32"
+};
+function Combinator(text, line, col){
+
+ SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE);
+ this.type = "unknown";
+ if (/^\s+$/.test(text)){
+ this.type = "descendant";
+ } else if (text == ">"){
+ this.type = "child";
+ } else if (text == "+"){
+ this.type = "adjacent-sibling";
+ } else if (text == "~"){
+ this.type = "sibling";
+ }
+
+}
+
+Combinator.prototype = new SyntaxUnit();
+Combinator.prototype.constructor = Combinator;
+function MediaFeature(name, value){
+
+ SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE);
+ this.name = name;
+ this.value = value;
+}
+
+MediaFeature.prototype = new SyntaxUnit();
+MediaFeature.prototype.constructor = MediaFeature;
+function MediaQuery(modifier, mediaType, features, line, col){
+
+ SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType + " " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE);
+ this.modifier = modifier;
+ this.mediaType = mediaType;
+ this.features = features;
+
+}
+
+MediaQuery.prototype = new SyntaxUnit();
+MediaQuery.prototype.constructor = MediaQuery;
+function Parser(options){
+ EventTarget.call(this);
+
+
+ this.options = options || {};
+
+ this._tokenStream = null;
+}
+Parser.DEFAULT_TYPE = 0;
+Parser.COMBINATOR_TYPE = 1;
+Parser.MEDIA_FEATURE_TYPE = 2;
+Parser.MEDIA_QUERY_TYPE = 3;
+Parser.PROPERTY_NAME_TYPE = 4;
+Parser.PROPERTY_VALUE_TYPE = 5;
+Parser.PROPERTY_VALUE_PART_TYPE = 6;
+Parser.SELECTOR_TYPE = 7;
+Parser.SELECTOR_PART_TYPE = 8;
+Parser.SELECTOR_SUB_PART_TYPE = 9;
+
+Parser.prototype = function(){
+
+ var proto = new EventTarget(), //new prototype
+ prop,
+ additions = {
+ constructor: Parser,
+ DEFAULT_TYPE : 0,
+ COMBINATOR_TYPE : 1,
+ MEDIA_FEATURE_TYPE : 2,
+ MEDIA_QUERY_TYPE : 3,
+ PROPERTY_NAME_TYPE : 4,
+ PROPERTY_VALUE_TYPE : 5,
+ PROPERTY_VALUE_PART_TYPE : 6,
+ SELECTOR_TYPE : 7,
+ SELECTOR_PART_TYPE : 8,
+ SELECTOR_SUB_PART_TYPE : 9,
+
+ _stylesheet: function(){
+
+ var tokenStream = this._tokenStream,
+ charset = null,
+ count,
+ token,
+ tt;
+
+ this.fire("startstylesheet");
+ this._charset();
+
+ this._skipCruft();
+ while (tokenStream.peek() == Tokens.IMPORT_SYM){
+ this._import();
+ this._skipCruft();
+ }
+ while (tokenStream.peek() == Tokens.NAMESPACE_SYM){
+ this._namespace();
+ this._skipCruft();
+ }
+ tt = tokenStream.peek();
+ while(tt > Tokens.EOF){
+
+ try {
+
+ switch(tt){
+ case Tokens.MEDIA_SYM:
+ this._media();
+ this._skipCruft();
+ break;
+ case Tokens.PAGE_SYM:
+ this._page();
+ this._skipCruft();
+ break;
+ case Tokens.FONT_FACE_SYM:
+ this._font_face();
+ this._skipCruft();
+ break;
+ case Tokens.KEYFRAMES_SYM:
+ this._keyframes();
+ this._skipCruft();
+ break;
+ case Tokens.UNKNOWN_SYM: //unknown @ rule
+ tokenStream.get();
+ if (!this.options.strict){
+ this.fire({
+ type: "error",
+ error: null,
+ message: "Unknown @ rule: " + tokenStream.LT(0).value + ".",
+ line: tokenStream.LT(0).startLine,
+ col: tokenStream.LT(0).startCol
+ });
+ count=0;
+ while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){
+ count++; //keep track of nesting depth
+ }
+
+ while(count){
+ tokenStream.advance([Tokens.RBRACE]);
+ count--;
+ }
+
+ } else {
+ throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);
+ }
+ break;
+ case Tokens.S:
+ this._readWhitespace();
+ break;
+ default:
+ if(!this._ruleset()){
+ switch(tt){
+ case Tokens.CHARSET_SYM:
+ token = tokenStream.LT(1);
+ this._charset(false);
+ throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol);
+ case Tokens.IMPORT_SYM:
+ token = tokenStream.LT(1);
+ this._import(false);
+ throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol);
+ case Tokens.NAMESPACE_SYM:
+ token = tokenStream.LT(1);
+ this._namespace(false);
+ throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol);
+ default:
+ tokenStream.get(); //get the last token
+ this._unexpectedToken(tokenStream.token());
+ }
+
+ }
+ }
+ } catch(ex) {
+ if (ex instanceof SyntaxError && !this.options.strict){
+ this.fire({
+ type: "error",
+ error: ex,
+ message: ex.message,
+ line: ex.line,
+ col: ex.col
+ });
+ } else {
+ throw ex;
+ }
+ }
+
+ tt = tokenStream.peek();
+ }
+
+ if (tt != Tokens.EOF){
+ this._unexpectedToken(tokenStream.token());
+ }
+
+ this.fire("endstylesheet");
+ },
+
+ _charset: function(emit){
+ var tokenStream = this._tokenStream,
+ charset,
+ token,
+ line,
+ col;
+
+ if (tokenStream.match(Tokens.CHARSET_SYM)){
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+
+ this._readWhitespace();
+ tokenStream.mustMatch(Tokens.STRING);
+
+ token = tokenStream.token();
+ charset = token.value;
+
+ this._readWhitespace();
+ tokenStream.mustMatch(Tokens.SEMICOLON);
+
+ if (emit !== false){
+ this.fire({
+ type: "charset",
+ charset:charset,
+ line: line,
+ col: col
+ });
+ }
+ }
+ },
+
+ _import: function(emit){
+
+ var tokenStream = this._tokenStream,
+ tt,
+ uri,
+ importToken,
+ mediaList = [];
+ tokenStream.mustMatch(Tokens.IMPORT_SYM);
+ importToken = tokenStream.token();
+ this._readWhitespace();
+
+ tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);
+ uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");
+
+ this._readWhitespace();
+
+ mediaList = this._media_query_list();
+ tokenStream.mustMatch(Tokens.SEMICOLON);
+ this._readWhitespace();
+
+ if (emit !== false){
+ this.fire({
+ type: "import",
+ uri: uri,
+ media: mediaList,
+ line: importToken.startLine,
+ col: importToken.startCol
+ });
+ }
+
+ },
+
+ _namespace: function(emit){
+
+ var tokenStream = this._tokenStream,
+ line,
+ col,
+ prefix,
+ uri;
+ tokenStream.mustMatch(Tokens.NAMESPACE_SYM);
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+ this._readWhitespace();
+ if (tokenStream.match(Tokens.IDENT)){
+ prefix = tokenStream.token().value;
+ this._readWhitespace();
+ }
+
+ tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);
+ uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");
+
+ this._readWhitespace();
+ tokenStream.mustMatch(Tokens.SEMICOLON);
+ this._readWhitespace();
+
+ if (emit !== false){
+ this.fire({
+ type: "namespace",
+ prefix: prefix,
+ uri: uri,
+ line: line,
+ col: col
+ });
+ }
+
+ },
+
+ _media: function(){
+ var tokenStream = this._tokenStream,
+ line,
+ col,
+ mediaList;// = [];
+ tokenStream.mustMatch(Tokens.MEDIA_SYM);
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+
+ this._readWhitespace();
+
+ mediaList = this._media_query_list();
+
+ tokenStream.mustMatch(Tokens.LBRACE);
+ this._readWhitespace();
+
+ this.fire({
+ type: "startmedia",
+ media: mediaList,
+ line: line,
+ col: col
+ });
+
+ while(true) {
+ if (tokenStream.peek() == Tokens.PAGE_SYM){
+ this._page();
+ } else if (!this._ruleset()){
+ break;
+ }
+ }
+
+ tokenStream.mustMatch(Tokens.RBRACE);
+ this._readWhitespace();
+
+ this.fire({
+ type: "endmedia",
+ media: mediaList,
+ line: line,
+ col: col
+ });
+ },
+ _media_query_list: function(){
+ var tokenStream = this._tokenStream,
+ mediaList = [];
+
+
+ this._readWhitespace();
+
+ if (tokenStream.peek() == Tokens.IDENT || tokenStream.peek() == Tokens.LPAREN){
+ mediaList.push(this._media_query());
+ }
+
+ while(tokenStream.match(Tokens.COMMA)){
+ this._readWhitespace();
+ mediaList.push(this._media_query());
+ }
+
+ return mediaList;
+ },
+ _media_query: function(){
+ var tokenStream = this._tokenStream,
+ type = null,
+ ident = null,
+ token = null,
+ expressions = [];
+
+ if (tokenStream.match(Tokens.IDENT)){
+ ident = tokenStream.token().value.toLowerCase();
+ if (ident != "only" && ident != "not"){
+ tokenStream.unget();
+ ident = null;
+ } else {
+ token = tokenStream.token();
+ }
+ }
+
+ this._readWhitespace();
+
+ if (tokenStream.peek() == Tokens.IDENT){
+ type = this._media_type();
+ if (token === null){
+ token = tokenStream.token();
+ }
+ } else if (tokenStream.peek() == Tokens.LPAREN){
+ if (token === null){
+ token = tokenStream.LT(1);
+ }
+ expressions.push(this._media_expression());
+ }
+
+ if (type === null && expressions.length === 0){
+ return null;
+ } else {
+ this._readWhitespace();
+ while (tokenStream.match(Tokens.IDENT)){
+ if (tokenStream.token().value.toLowerCase() != "and"){
+ this._unexpectedToken(tokenStream.token());
+ }
+
+ this._readWhitespace();
+ expressions.push(this._media_expression());
+ }
+ }
+
+ return new MediaQuery(ident, type, expressions, token.startLine, token.startCol);
+ },
+ _media_type: function(){
+ return this._media_feature();
+ },
+ _media_expression: function(){
+ var tokenStream = this._tokenStream,
+ feature = null,
+ token,
+ expression = null;
+
+ tokenStream.mustMatch(Tokens.LPAREN);
+
+ feature = this._media_feature();
+ this._readWhitespace();
+
+ if (tokenStream.match(Tokens.COLON)){
+ this._readWhitespace();
+ token = tokenStream.LT(1);
+ expression = this._expression();
+ }
+
+ tokenStream.mustMatch(Tokens.RPAREN);
+ this._readWhitespace();
+
+ return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null));
+ },
+ _media_feature: function(){
+ var tokenStream = this._tokenStream;
+
+ tokenStream.mustMatch(Tokens.IDENT);
+
+ return SyntaxUnit.fromToken(tokenStream.token());
+ },
+ _page: function(){
+ var tokenStream = this._tokenStream,
+ line,
+ col,
+ identifier = null,
+ pseudoPage = null;
+ tokenStream.mustMatch(Tokens.PAGE_SYM);
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+
+ this._readWhitespace();
+
+ if (tokenStream.match(Tokens.IDENT)){
+ identifier = tokenStream.token().value;
+ if (identifier.toLowerCase() === "auto"){
+ this._unexpectedToken(tokenStream.token());
+ }
+ }
+ if (tokenStream.peek() == Tokens.COLON){
+ pseudoPage = this._pseudo_page();
+ }
+
+ this._readWhitespace();
+
+ this.fire({
+ type: "startpage",
+ id: identifier,
+ pseudo: pseudoPage,
+ line: line,
+ col: col
+ });
+
+ this._readDeclarations(true, true);
+
+ this.fire({
+ type: "endpage",
+ id: identifier,
+ pseudo: pseudoPage,
+ line: line,
+ col: col
+ });
+
+ },
+ _margin: function(){
+ var tokenStream = this._tokenStream,
+ line,
+ col,
+ marginSym = this._margin_sym();
+
+ if (marginSym){
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+
+ this.fire({
+ type: "startpagemargin",
+ margin: marginSym,
+ line: line,
+ col: col
+ });
+
+ this._readDeclarations(true);
+
+ this.fire({
+ type: "endpagemargin",
+ margin: marginSym,
+ line: line,
+ col: col
+ });
+ return true;
+ } else {
+ return false;
+ }
+ },
+ _margin_sym: function(){
+
+ var tokenStream = this._tokenStream;
+
+ if(tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM,
+ Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM,
+ Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM,
+ Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM,
+ Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM,
+ Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM,
+ Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM]))
+ {
+ return SyntaxUnit.fromToken(tokenStream.token());
+ } else {
+ return null;
+ }
+
+ },
+
+ _pseudo_page: function(){
+
+ var tokenStream = this._tokenStream;
+
+ tokenStream.mustMatch(Tokens.COLON);
+ tokenStream.mustMatch(Tokens.IDENT);
+
+ return tokenStream.token().value;
+ },
+
+ _font_face: function(){
+ var tokenStream = this._tokenStream,
+ line,
+ col;
+ tokenStream.mustMatch(Tokens.FONT_FACE_SYM);
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+
+ this._readWhitespace();
+
+ this.fire({
+ type: "startfontface",
+ line: line,
+ col: col
+ });
+
+ this._readDeclarations(true);
+
+ this.fire({
+ type: "endfontface",
+ line: line,
+ col: col
+ });
+ },
+
+ _operator: function(){
+
+ var tokenStream = this._tokenStream,
+ token = null;
+
+ if (tokenStream.match([Tokens.SLASH, Tokens.COMMA])){
+ token = tokenStream.token();
+ this._readWhitespace();
+ }
+ return token ? PropertyValuePart.fromToken(token) : null;
+
+ },
+
+ _combinator: function(){
+
+ var tokenStream = this._tokenStream,
+ value = null,
+ token;
+
+ if(tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])){
+ token = tokenStream.token();
+ value = new Combinator(token.value, token.startLine, token.startCol);
+ this._readWhitespace();
+ }
+
+ return value;
+ },
+
+ _unary_operator: function(){
+
+ var tokenStream = this._tokenStream;
+
+ if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){
+ return tokenStream.token().value;
+ } else {
+ return null;
+ }
+ },
+
+ _property: function(){
+
+ var tokenStream = this._tokenStream,
+ value = null,
+ hack = null,
+ tokenValue,
+ token,
+ line,
+ col;
+ if (tokenStream.peek() == Tokens.STAR && this.options.starHack){
+ tokenStream.get();
+ token = tokenStream.token();
+ hack = token.value;
+ line = token.startLine;
+ col = token.startCol;
+ }
+
+ if(tokenStream.match(Tokens.IDENT)){
+ token = tokenStream.token();
+ tokenValue = token.value;
+ if (tokenValue.charAt(0) == "_" && this.options.underscoreHack){
+ hack = "_";
+ tokenValue = tokenValue.substring(1);
+ }
+
+ value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol));
+ this._readWhitespace();
+ }
+
+ return value;
+ },
+ _ruleset: function(){
+
+ var tokenStream = this._tokenStream,
+ tt,
+ selectors;
+ try {
+ selectors = this._selectors_group();
+ } catch (ex){
+ if (ex instanceof SyntaxError && !this.options.strict){
+ this.fire({
+ type: "error",
+ error: ex,
+ message: ex.message,
+ line: ex.line,
+ col: ex.col
+ });
+ tt = tokenStream.advance([Tokens.RBRACE]);
+ if (tt == Tokens.RBRACE){
+ } else {
+ throw ex;
+ }
+
+ } else {
+ throw ex;
+ }
+ return true;
+ }
+ if (selectors){
+
+ this.fire({
+ type: "startrule",
+ selectors: selectors,
+ line: selectors[0].line,
+ col: selectors[0].col
+ });
+
+ this._readDeclarations(true);
+
+ this.fire({
+ type: "endrule",
+ selectors: selectors,
+ line: selectors[0].line,
+ col: selectors[0].col
+ });
+
+ }
+
+ return selectors;
+
+ },
+ _selectors_group: function(){
+ var tokenStream = this._tokenStream,
+ selectors = [],
+ selector;
+
+ selector = this._selector();
+ if (selector !== null){
+
+ selectors.push(selector);
+ while(tokenStream.match(Tokens.COMMA)){
+ this._readWhitespace();
+ selector = this._selector();
+ if (selector !== null){
+ selectors.push(selector);
+ } else {
+ this._unexpectedToken(tokenStream.LT(1));
+ }
+ }
+ }
+
+ return selectors.length ? selectors : null;
+ },
+ _selector: function(){
+
+ var tokenStream = this._tokenStream,
+ selector = [],
+ nextSelector = null,
+ combinator = null,
+ ws = null;
+ nextSelector = this._simple_selector_sequence();
+ if (nextSelector === null){
+ return null;
+ }
+
+ selector.push(nextSelector);
+
+ do {
+ combinator = this._combinator();
+
+ if (combinator !== null){
+ selector.push(combinator);
+ nextSelector = this._simple_selector_sequence();
+ if (nextSelector === null){
+ this._unexpectedToken(tokenStream.LT(1));
+ } else {
+ selector.push(nextSelector);
+ }
+ } else {
+ if (this._readWhitespace()){
+ ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol);
+ combinator = this._combinator();
+ nextSelector = this._simple_selector_sequence();
+ if (nextSelector === null){
+ if (combinator !== null){
+ this._unexpectedToken(tokenStream.LT(1));
+ }
+ } else {
+
+ if (combinator !== null){
+ selector.push(combinator);
+ } else {
+ selector.push(ws);
+ }
+
+ selector.push(nextSelector);
+ }
+ } else {
+ break;
+ }
+
+ }
+ } while(true);
+
+ return new Selector(selector, selector[0].line, selector[0].col);
+ },
+ _simple_selector_sequence: function(){
+
+ var tokenStream = this._tokenStream,
+ elementName = null,
+ modifiers = [],
+ selectorText= "",
+ components = [
+ function(){
+ return tokenStream.match(Tokens.HASH) ?
+ new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) :
+ null;
+ },
+ this._class,
+ this._attrib,
+ this._pseudo,
+ this._negation
+ ],
+ i = 0,
+ len = components.length,
+ component = null,
+ found = false,
+ line,
+ col;
+ line = tokenStream.LT(1).startLine;
+ col = tokenStream.LT(1).startCol;
+
+ elementName = this._type_selector();
+ if (!elementName){
+ elementName = this._universal();
+ }
+
+ if (elementName !== null){
+ selectorText += elementName;
+ }
+
+ while(true){
+ if (tokenStream.peek() === Tokens.S){
+ break;
+ }
+ while(i < len && component === null){
+ component = components[i++].call(this);
+ }
+
+ if (component === null){
+ if (selectorText === ""){
+ return null;
+ } else {
+ break;
+ }
+ } else {
+ i = 0;
+ modifiers.push(component);
+ selectorText += component.toString();
+ component = null;
+ }
+ }
+
+
+ return selectorText !== "" ?
+ new SelectorPart(elementName, modifiers, selectorText, line, col) :
+ null;
+ },
+ _type_selector: function(){
+
+ var tokenStream = this._tokenStream,
+ ns = this._namespace_prefix(),
+ elementName = this._element_name();
+
+ if (!elementName){
+ if (ns){
+ tokenStream.unget();
+ if (ns.length > 1){
+ tokenStream.unget();
+ }
+ }
+
+ return null;
+ } else {
+ if (ns){
+ elementName.text = ns + elementName.text;
+ elementName.col -= ns.length;
+ }
+ return elementName;
+ }
+ },
+ _class: function(){
+
+ var tokenStream = this._tokenStream,
+ token;
+
+ if (tokenStream.match(Tokens.DOT)){
+ tokenStream.mustMatch(Tokens.IDENT);
+ token = tokenStream.token();
+ return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1);
+ } else {
+ return null;
+ }
+
+ },
+ _element_name: function(){
+
+ var tokenStream = this._tokenStream,
+ token;
+
+ if (tokenStream.match(Tokens.IDENT)){
+ token = tokenStream.token();
+ return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol);
+
+ } else {
+ return null;
+ }
+ },
+ _namespace_prefix: function(){
+ var tokenStream = this._tokenStream,
+ value = "";
+ if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){
+
+ if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){
+ value += tokenStream.token().value;
+ }
+
+ tokenStream.mustMatch(Tokens.PIPE);
+ value += "|";
+
+ }
+
+ return value.length ? value : null;
+ },
+ _universal: function(){
+ var tokenStream = this._tokenStream,
+ value = "",
+ ns;
+
+ ns = this._namespace_prefix();
+ if(ns){
+ value += ns;
+ }
+
+ if(tokenStream.match(Tokens.STAR)){
+ value += "*";
+ }
+
+ return value.length ? value : null;
+
+ },
+ _attrib: function(){
+
+ var tokenStream = this._tokenStream,
+ value = null,
+ ns,
+ token;
+
+ if (tokenStream.match(Tokens.LBRACKET)){
+ token = tokenStream.token();
+ value = token.value;
+ value += this._readWhitespace();
+
+ ns = this._namespace_prefix();
+
+ if (ns){
+ value += ns;
+ }
+
+ tokenStream.mustMatch(Tokens.IDENT);
+ value += tokenStream.token().value;
+ value += this._readWhitespace();
+
+ if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH,
+ Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){
+
+ value += tokenStream.token().value;
+ value += this._readWhitespace();
+
+ tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
+ value += tokenStream.token().value;
+ value += this._readWhitespace();
+ }
+
+ tokenStream.mustMatch(Tokens.RBRACKET);
+
+ return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol);
+ } else {
+ return null;
+ }
+ },
+ _pseudo: function(){
+
+ var tokenStream = this._tokenStream,
+ pseudo = null,
+ colons = ":",
+ line,
+ col;
+
+ if (tokenStream.match(Tokens.COLON)){
+
+ if (tokenStream.match(Tokens.COLON)){
+ colons += ":";
+ }
+
+ if (tokenStream.match(Tokens.IDENT)){
+ pseudo = tokenStream.token().value;
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol - colons.length;
+ } else if (tokenStream.peek() == Tokens.FUNCTION){
+ line = tokenStream.LT(1).startLine;
+ col = tokenStream.LT(1).startCol - colons.length;
+ pseudo = this._functional_pseudo();
+ }
+
+ if (pseudo){
+ pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col);
+ }
+ }
+
+ return pseudo;
+ },
+ _functional_pseudo: function(){
+
+ var tokenStream = this._tokenStream,
+ value = null;
+
+ if(tokenStream.match(Tokens.FUNCTION)){
+ value = tokenStream.token().value;
+ value += this._readWhitespace();
+ value += this._expression();
+ tokenStream.mustMatch(Tokens.RPAREN);
+ value += ")";
+ }
+
+ return value;
+ },
+ _expression: function(){
+
+ var tokenStream = this._tokenStream,
+ value = "";
+
+ while(tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION,
+ Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH,
+ Tokens.FREQ, Tokens.ANGLE, Tokens.TIME,
+ Tokens.RESOLUTION])){
+
+ value += tokenStream.token().value;
+ value += this._readWhitespace();
+ }
+
+ return value.length ? value : null;
+
+ },
+ _negation: function(){
+
+ var tokenStream = this._tokenStream,
+ line,
+ col,
+ value = "",
+ arg,
+ subpart = null;
+
+ if (tokenStream.match(Tokens.NOT)){
+ value = tokenStream.token().value;
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+ value += this._readWhitespace();
+ arg = this._negation_arg();
+ value += arg;
+ value += this._readWhitespace();
+ tokenStream.match(Tokens.RPAREN);
+ value += tokenStream.token().value;
+
+ subpart = new SelectorSubPart(value, "not", line, col);
+ subpart.args.push(arg);
+ }
+
+ return subpart;
+ },
+ _negation_arg: function(){
+
+ var tokenStream = this._tokenStream,
+ args = [
+ this._type_selector,
+ this._universal,
+ function(){
+ return tokenStream.match(Tokens.HASH) ?
+ new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) :
+ null;
+ },
+ this._class,
+ this._attrib,
+ this._pseudo
+ ],
+ arg = null,
+ i = 0,
+ len = args.length,
+ elementName,
+ line,
+ col,
+ part;
+
+ line = tokenStream.LT(1).startLine;
+ col = tokenStream.LT(1).startCol;
+
+ while(i < len && arg === null){
+
+ arg = args[i].call(this);
+ i++;
+ }
+ if (arg === null){
+ this._unexpectedToken(tokenStream.LT(1));
+ }
+ if (arg.type == "elementName"){
+ part = new SelectorPart(arg, [], arg.toString(), line, col);
+ } else {
+ part = new SelectorPart(null, [arg], arg.toString(), line, col);
+ }
+
+ return part;
+ },
+
+ _declaration: function(){
+
+ var tokenStream = this._tokenStream,
+ property = null,
+ expr = null,
+ prio = null,
+ error = null,
+ invalid = null,
+ propertyName= "";
+
+ property = this._property();
+ if (property !== null){
+
+ tokenStream.mustMatch(Tokens.COLON);
+ this._readWhitespace();
+
+ expr = this._expr();
+ if (!expr || expr.length === 0){
+ this._unexpectedToken(tokenStream.LT(1));
+ }
+
+ prio = this._prio();
+ propertyName = property.toString();
+ if (this.options.starHack && property.hack == "*" ||
+ this.options.underscoreHack && property.hack == "_") {
+
+ propertyName = property.text;
+ }
+
+ try {
+ this._validateProperty(propertyName, expr);
+ } catch (ex) {
+ invalid = ex;
+ }
+
+ this.fire({
+ type: "property",
+ property: property,
+ value: expr,
+ important: prio,
+ line: property.line,
+ col: property.col,
+ invalid: invalid
+ });
+
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ _prio: function(){
+
+ var tokenStream = this._tokenStream,
+ result = tokenStream.match(Tokens.IMPORTANT_SYM);
+
+ this._readWhitespace();
+ return result;
+ },
+
+ _expr: function(){
+
+ var tokenStream = this._tokenStream,
+ values = [],
+ value = null,
+ operator = null;
+
+ value = this._term();
+ if (value !== null){
+
+ values.push(value);
+
+ do {
+ operator = this._operator();
+ if (operator){
+ values.push(operator);
+ } /*else {
+ values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));
+ valueParts = [];
+ }*/
+
+ value = this._term();
+
+ if (value === null){
+ break;
+ } else {
+ values.push(value);
+ }
+ } while(true);
+ }
+
+ return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null;
+ },
+
+ _term: function(){
+
+ var tokenStream = this._tokenStream,
+ unary = null,
+ value = null,
+ token,
+ line,
+ col;
+ unary = this._unary_operator();
+ if (unary !== null){
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+ }
+ if (tokenStream.peek() == Tokens.IE_FUNCTION && this.options.ieFilters){
+
+ value = this._ie_function();
+ if (unary === null){
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+ }
+ } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH,
+ Tokens.ANGLE, Tokens.TIME,
+ Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])){
+
+ value = tokenStream.token().value;
+ if (unary === null){
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+ }
+ this._readWhitespace();
+ } else {
+ token = this._hexcolor();
+ if (token === null){
+ if (unary === null){
+ line = tokenStream.LT(1).startLine;
+ col = tokenStream.LT(1).startCol;
+ }
+ if (value === null){
+ if (tokenStream.LA(3) == Tokens.EQUALS && this.options.ieFilters){
+ value = this._ie_function();
+ } else {
+ value = this._function();
+ }
+ }
+
+ } else {
+ value = token.value;
+ if (unary === null){
+ line = token.startLine;
+ col = token.startCol;
+ }
+ }
+
+ }
+
+ return value !== null ?
+ new PropertyValuePart(unary !== null ? unary + value : value, line, col) :
+ null;
+
+ },
+
+ _function: function(){
+
+ var tokenStream = this._tokenStream,
+ functionText = null,
+ expr = null,
+ lt;
+
+ if (tokenStream.match(Tokens.FUNCTION)){
+ functionText = tokenStream.token().value;
+ this._readWhitespace();
+ expr = this._expr();
+ functionText += expr;
+ if (this.options.ieFilters && tokenStream.peek() == Tokens.EQUALS){
+ do {
+
+ if (this._readWhitespace()){
+ functionText += tokenStream.token().value;
+ }
+ if (tokenStream.LA(0) == Tokens.COMMA){
+ functionText += tokenStream.token().value;
+ }
+
+ tokenStream.match(Tokens.IDENT);
+ functionText += tokenStream.token().value;
+
+ tokenStream.match(Tokens.EQUALS);
+ functionText += tokenStream.token().value;
+ lt = tokenStream.peek();
+ while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){
+ tokenStream.get();
+ functionText += tokenStream.token().value;
+ lt = tokenStream.peek();
+ }
+ } while(tokenStream.match([Tokens.COMMA, Tokens.S]));
+ }
+
+ tokenStream.match(Tokens.RPAREN);
+ functionText += ")";
+ this._readWhitespace();
+ }
+
+ return functionText;
+ },
+
+ _ie_function: function(){
+
+ var tokenStream = this._tokenStream,
+ functionText = null,
+ expr = null,
+ lt;
+ if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])){
+ functionText = tokenStream.token().value;
+
+ do {
+
+ if (this._readWhitespace()){
+ functionText += tokenStream.token().value;
+ }
+ if (tokenStream.LA(0) == Tokens.COMMA){
+ functionText += tokenStream.token().value;
+ }
+
+ tokenStream.match(Tokens.IDENT);
+ functionText += tokenStream.token().value;
+
+ tokenStream.match(Tokens.EQUALS);
+ functionText += tokenStream.token().value;
+ lt = tokenStream.peek();
+ while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){
+ tokenStream.get();
+ functionText += tokenStream.token().value;
+ lt = tokenStream.peek();
+ }
+ } while(tokenStream.match([Tokens.COMMA, Tokens.S]));
+
+ tokenStream.match(Tokens.RPAREN);
+ functionText += ")";
+ this._readWhitespace();
+ }
+
+ return functionText;
+ },
+
+ _hexcolor: function(){
+
+ var tokenStream = this._tokenStream,
+ token = null,
+ color;
+
+ if(tokenStream.match(Tokens.HASH)){
+
+ token = tokenStream.token();
+ color = token.value;
+ if (!/#[a-f0-9]{3,6}/i.test(color)){
+ throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
+ }
+ this._readWhitespace();
+ }
+
+ return token;
+ },
+
+ _keyframes: function(){
+ var tokenStream = this._tokenStream,
+ token,
+ tt,
+ name,
+ prefix = "";
+
+ tokenStream.mustMatch(Tokens.KEYFRAMES_SYM);
+ token = tokenStream.token();
+ if (/^@\-([^\-]+)\-/.test(token.value)) {
+ prefix = RegExp.$1;
+ }
+
+ this._readWhitespace();
+ name = this._keyframe_name();
+
+ this._readWhitespace();
+ tokenStream.mustMatch(Tokens.LBRACE);
+
+ this.fire({
+ type: "startkeyframes",
+ name: name,
+ prefix: prefix,
+ line: token.startLine,
+ col: token.startCol
+ });
+
+ this._readWhitespace();
+ tt = tokenStream.peek();
+ while(tt == Tokens.IDENT || tt == Tokens.PERCENTAGE) {
+ this._keyframe_rule();
+ this._readWhitespace();
+ tt = tokenStream.peek();
+ }
+
+ this.fire({
+ type: "endkeyframes",
+ name: name,
+ prefix: prefix,
+ line: token.startLine,
+ col: token.startCol
+ });
+
+ this._readWhitespace();
+ tokenStream.mustMatch(Tokens.RBRACE);
+
+ },
+
+ _keyframe_name: function(){
+ var tokenStream = this._tokenStream,
+ token;
+
+ tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
+ return SyntaxUnit.fromToken(tokenStream.token());
+ },
+
+ _keyframe_rule: function(){
+ var tokenStream = this._tokenStream,
+ token,
+ keyList = this._key_list();
+
+ this.fire({
+ type: "startkeyframerule",
+ keys: keyList,
+ line: keyList[0].line,
+ col: keyList[0].col
+ });
+
+ this._readDeclarations(true);
+
+ this.fire({
+ type: "endkeyframerule",
+ keys: keyList,
+ line: keyList[0].line,
+ col: keyList[0].col
+ });
+
+ },
+
+ _key_list: function(){
+ var tokenStream = this._tokenStream,
+ token,
+ key,
+ keyList = [];
+ keyList.push(this._key());
+
+ this._readWhitespace();
+
+ while(tokenStream.match(Tokens.COMMA)){
+ this._readWhitespace();
+ keyList.push(this._key());
+ this._readWhitespace();
+ }
+
+ return keyList;
+ },
+
+ _key: function(){
+
+ var tokenStream = this._tokenStream,
+ token;
+
+ if (tokenStream.match(Tokens.PERCENTAGE)){
+ return SyntaxUnit.fromToken(tokenStream.token());
+ } else if (tokenStream.match(Tokens.IDENT)){
+ token = tokenStream.token();
+
+ if (/from|to/i.test(token.value)){
+ return SyntaxUnit.fromToken(token);
+ }
+
+ tokenStream.unget();
+ }
+ this._unexpectedToken(tokenStream.LT(1));
+ },
+ _skipCruft: function(){
+ while(this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])){
+ }
+ },
+ _readDeclarations: function(checkStart, readMargins){
+ var tokenStream = this._tokenStream,
+ tt;
+
+
+ this._readWhitespace();
+
+ if (checkStart){
+ tokenStream.mustMatch(Tokens.LBRACE);
+ }
+
+ this._readWhitespace();
+
+ try {
+
+ while(true){
+
+ if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())){
+ } else if (this._declaration()){
+ if (!tokenStream.match(Tokens.SEMICOLON)){
+ break;
+ }
+ } else {
+ break;
+ }
+ this._readWhitespace();
+ }
+
+ tokenStream.mustMatch(Tokens.RBRACE);
+ this._readWhitespace();
+
+ } catch (ex) {
+ if (ex instanceof SyntaxError && !this.options.strict){
+ this.fire({
+ type: "error",
+ error: ex,
+ message: ex.message,
+ line: ex.line,
+ col: ex.col
+ });
+ tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]);
+ if (tt == Tokens.SEMICOLON){
+ this._readDeclarations(false, readMargins);
+ } else if (tt != Tokens.RBRACE){
+ throw ex;
+ }
+
+ } else {
+ throw ex;
+ }
+ }
+
+ },
+ _readWhitespace: function(){
+
+ var tokenStream = this._tokenStream,
+ ws = "";
+
+ while(tokenStream.match(Tokens.S)){
+ ws += tokenStream.token().value;
+ }
+
+ return ws;
+ },
+ _unexpectedToken: function(token){
+ throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
+ },
+ _verifyEnd: function(){
+ if (this._tokenStream.LA(1) != Tokens.EOF){
+ this._unexpectedToken(this._tokenStream.LT(1));
+ }
+ },
+ _validateProperty: function(property, value){
+ Validation.validate(property, value);
+ },
+
+ parse: function(input){
+ this._tokenStream = new TokenStream(input, Tokens);
+ this._stylesheet();
+ },
+
+ parseStyleSheet: function(input){
+ return this.parse(input);
+ },
+
+ parseMediaQuery: function(input){
+ this._tokenStream = new TokenStream(input, Tokens);
+ var result = this._media_query();
+ this._verifyEnd();
+ return result;
+ },
+ parsePropertyValue: function(input){
+
+ this._tokenStream = new TokenStream(input, Tokens);
+ this._readWhitespace();
+
+ var result = this._expr();
+ this._readWhitespace();
+ this._verifyEnd();
+ return result;
+ },
+ parseRule: function(input){
+ this._tokenStream = new TokenStream(input, Tokens);
+ this._readWhitespace();
+
+ var result = this._ruleset();
+ this._readWhitespace();
+ this._verifyEnd();
+ return result;
+ },
+ parseSelector: function(input){
+
+ this._tokenStream = new TokenStream(input, Tokens);
+ this._readWhitespace();
+
+ var result = this._selector();
+ this._readWhitespace();
+ this._verifyEnd();
+ return result;
+ },
+ parseStyleAttribute: function(input){
+ input += "}"; // for error recovery in _readDeclarations()
+ this._tokenStream = new TokenStream(input, Tokens);
+ this._readDeclarations();
+ }
+ };
+ for (prop in additions){
+ if (additions.hasOwnProperty(prop)){
+ proto[prop] = additions[prop];
+ }
+ }
+
+ return proto;
+}();
+var Properties = {
+ "alignment-adjust" : "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | <percentage> | <length>",
+ "alignment-baseline" : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
+ "animation" : 1,
+ "animation-delay" : { multi: "<time>", comma: true },
+ "animation-direction" : { multi: "normal | alternate", comma: true },
+ "animation-duration" : { multi: "<time>", comma: true },
+ "animation-iteration-count" : { multi: "<number> | infinite", comma: true },
+ "animation-name" : { multi: "none | <ident>", comma: true },
+ "animation-play-state" : { multi: "running | paused", comma: true },
+ "animation-timing-function" : 1,
+ "-moz-animation-delay" : { multi: "<time>", comma: true },
+ "-moz-animation-direction" : { multi: "normal | alternate", comma: true },
+ "-moz-animation-duration" : { multi: "<time>", comma: true },
+ "-moz-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
+ "-moz-animation-name" : { multi: "none | <ident>", comma: true },
+ "-moz-animation-play-state" : { multi: "running | paused", comma: true },
+
+ "-ms-animation-delay" : { multi: "<time>", comma: true },
+ "-ms-animation-direction" : { multi: "normal | alternate", comma: true },
+ "-ms-animation-duration" : { multi: "<time>", comma: true },
+ "-ms-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
+ "-ms-animation-name" : { multi: "none | <ident>", comma: true },
+ "-ms-animation-play-state" : { multi: "running | paused", comma: true },
+
+ "-webkit-animation-delay" : { multi: "<time>", comma: true },
+ "-webkit-animation-direction" : { multi: "normal | alternate", comma: true },
+ "-webkit-animation-duration" : { multi: "<time>", comma: true },
+ "-webkit-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
+ "-webkit-animation-name" : { multi: "none | <ident>", comma: true },
+ "-webkit-animation-play-state" : { multi: "running | paused", comma: true },
+
+ "-o-animation-delay" : { multi: "<time>", comma: true },
+ "-o-animation-direction" : { multi: "normal | alternate", comma: true },
+ "-o-animation-duration" : { multi: "<time>", comma: true },
+ "-o-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
+ "-o-animation-name" : { multi: "none | <ident>", comma: true },
+ "-o-animation-play-state" : { multi: "running | paused", comma: true },
+
+ "appearance" : "icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | inherit",
+ "azimuth" : function (expression) {
+ var simple = "<angle> | leftwards | rightwards | inherit",
+ direction = "left-side | far-left | left | center-left | center | center-right | right | far-right | right-side",
+ behind = false,
+ valid = false,
+ part;
+
+ if (!ValidationTypes.isAny(expression, simple)) {
+ if (ValidationTypes.isAny(expression, "behind")) {
+ behind = true;
+ valid = true;
+ }
+
+ if (ValidationTypes.isAny(expression, direction)) {
+ valid = true;
+ if (!behind) {
+ ValidationTypes.isAny(expression, "behind");
+ }
+ }
+ }
+
+ if (expression.hasNext()) {
+ part = expression.next();
+ if (valid) {
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ } else {
+ throw new ValidationError("Expected (<'azimuth'>) but found '" + part + "'.", part.line, part.col);
+ }
+ }
+ },
+ "backface-visibility" : "visible | hidden",
+ "background" : 1,
+ "background-attachment" : { multi: "<attachment>", comma: true },
+ "background-clip" : { multi: "<box>", comma: true },
+ "background-color" : "<color> | inherit",
+ "background-image" : { multi: "<bg-image>", comma: true },
+ "background-origin" : { multi: "<box>", comma: true },
+ "background-position" : { multi: "<bg-position>", comma: true },
+ "background-repeat" : { multi: "<repeat-style>" },
+ "background-size" : { multi: "<bg-size>", comma: true },
+ "baseline-shift" : "baseline | sub | super | <percentage> | <length>",
+ "behavior" : 1,
+ "binding" : 1,
+ "bleed" : "<length>",
+ "bookmark-label" : "<content> | <attr> | <string>",
+ "bookmark-level" : "none | <integer>",
+ "bookmark-state" : "open | closed",
+ "bookmark-target" : "none | <uri> | <attr>",
+ "border" : "<border-width> || <border-style> || <color>",
+ "border-bottom" : "<border-width> || <border-style> || <color>",
+ "border-bottom-color" : "<color>",
+ "border-bottom-left-radius" : "<x-one-radius>",
+ "border-bottom-right-radius" : "<x-one-radius>",
+ "border-bottom-style" : "<border-style>",
+ "border-bottom-width" : "<border-width>",
+ "border-collapse" : "collapse | separate | inherit",
+ "border-color" : { multi: "<color> | inherit", max: 4 },
+ "border-image" : 1,
+ "border-image-outset" : { multi: "<length> | <number>", max: 4 },
+ "border-image-repeat" : { multi: "stretch | repeat | round", max: 2 },
+ "border-image-slice" : function(expression) {
+
+ var valid = false,
+ numeric = "<number> | <percentage>",
+ fill = false,
+ count = 0,
+ max = 4,
+ part;
+
+ if (ValidationTypes.isAny(expression, "fill")) {
+ fill = true;
+ valid = true;
+ }
+
+ while (expression.hasNext() && count < max) {
+ valid = ValidationTypes.isAny(expression, numeric);
+ if (!valid) {
+ break;
+ }
+ count++;
+ }
+
+
+ if (!fill) {
+ ValidationTypes.isAny(expression, "fill");
+ } else {
+ valid = true;
+ }
+
+ if (expression.hasNext()) {
+ part = expression.next();
+ if (valid) {
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ } else {
+ throw new ValidationError("Expected ([<number> | <percentage>]{1,4} && fill?) but found '" + part + "'.", part.line, part.col);
+ }
+ }
+ },
+ "border-image-source" : "<image> | none",
+ "border-image-width" : { multi: "<length> | <percentage> | <number> | auto", max: 4 },
+ "border-left" : "<border-width> || <border-style> || <color>",
+ "border-left-color" : "<color> | inherit",
+ "border-left-style" : "<border-style>",
+ "border-left-width" : "<border-width>",
+ "border-radius" : function(expression) {
+
+ var valid = false,
+ numeric = "<length> | <percentage>",
+ slash = false,
+ fill = false,
+ count = 0,
+ max = 8,
+ part;
+
+ while (expression.hasNext() && count < max) {
+ valid = ValidationTypes.isAny(expression, numeric);
+ if (!valid) {
+
+ if (expression.peek() == "/" && count > 1 && !slash) {
+ slash = true;
+ max = count + 5;
+ expression.next();
+ } else {
+ break;
+ }
+ }
+ count++;
+ }
+
+ if (expression.hasNext()) {
+ part = expression.next();
+ if (valid) {
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ } else {
+ throw new ValidationError("Expected (<'border-radius'>) but found '" + part + "'.", part.line, part.col);
+ }
+ }
+ },
+ "border-right" : "<border-width> || <border-style> || <color>",
+ "border-right-color" : "<color> | inherit",
+ "border-right-style" : "<border-style>",
+ "border-right-width" : "<border-width>",
+ "border-spacing" : { multi: "<length> | inherit", max: 2 },
+ "border-style" : { multi: "<border-style>", max: 4 },
+ "border-top" : "<border-width> || <border-style> || <color>",
+ "border-top-color" : "<color> | inherit",
+ "border-top-left-radius" : "<x-one-radius>",
+ "border-top-right-radius" : "<x-one-radius>",
+ "border-top-style" : "<border-style>",
+ "border-top-width" : "<border-width>",
+ "border-width" : { multi: "<border-width>", max: 4 },
+ "bottom" : "<margin-width> | inherit",
+ "box-align" : "start | end | center | baseline | stretch", //http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/
+ "box-decoration-break" : "slice |clone",
+ "box-direction" : "normal | reverse | inherit",
+ "box-flex" : "<number>",
+ "box-flex-group" : "<integer>",
+ "box-lines" : "single | multiple",
+ "box-ordinal-group" : "<integer>",
+ "box-orient" : "horizontal | vertical | inline-axis | block-axis | inherit",
+ "box-pack" : "start | end | center | justify",
+ "box-shadow" : function (expression) {
+ var result = false,
+ part;
+
+ if (!ValidationTypes.isAny(expression, "none")) {
+ Validation.multiProperty("<shadow>", expression, true, Infinity);
+ } else {
+ if (expression.hasNext()) {
+ part = expression.next();
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ }
+ }
+ },
+ "box-sizing" : "content-box | border-box | inherit",
+ "break-after" : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column",
+ "break-before" : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column",
+ "break-inside" : "auto | avoid | avoid-page | avoid-column",
+ "caption-side" : "top | bottom | inherit",
+ "clear" : "none | right | left | both | inherit",
+ "clip" : 1,
+ "color" : "<color> | inherit",
+ "color-profile" : 1,
+ "column-count" : "<integer> | auto", //http://www.w3.org/TR/css3-multicol/
+ "column-fill" : "auto | balance",
+ "column-gap" : "<length> | normal",
+ "column-rule" : "<border-width> || <border-style> || <color>",
+ "column-rule-color" : "<color>",
+ "column-rule-style" : "<border-style>",
+ "column-rule-width" : "<border-width>",
+ "column-span" : "none | all",
+ "column-width" : "<length> | auto",
+ "columns" : 1,
+ "content" : 1,
+ "counter-increment" : 1,
+ "counter-reset" : 1,
+ "crop" : "<shape> | auto",
+ "cue" : "cue-after | cue-before | inherit",
+ "cue-after" : 1,
+ "cue-before" : 1,
+ "cursor" : 1,
+ "direction" : "ltr | rtl | inherit",
+ "display" : "inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | box | inline-box | grid | inline-grid | none | inherit",
+ "dominant-baseline" : 1,
+ "drop-initial-after-adjust" : "central | middle | after-edge | text-after-edge | ideographic | alphabetic | mathematical | <percentage> | <length>",
+ "drop-initial-after-align" : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
+ "drop-initial-before-adjust" : "before-edge | text-before-edge | central | middle | hanging | mathematical | <percentage> | <length>",
+ "drop-initial-before-align" : "caps-height | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
+ "drop-initial-size" : "auto | line | <length> | <percentage>",
+ "drop-initial-value" : "initial | <integer>",
+ "elevation" : "<angle> | below | level | above | higher | lower | inherit",
+ "empty-cells" : "show | hide | inherit",
+ "filter" : 1,
+ "fit" : "fill | hidden | meet | slice",
+ "fit-position" : 1,
+ "float" : "left | right | none | inherit",
+ "float-offset" : 1,
+ "font" : 1,
+ "font-family" : 1,
+ "font-size" : "<absolute-size> | <relative-size> | <length> | <percentage> | inherit",
+ "font-size-adjust" : "<number> | none | inherit",
+ "font-stretch" : "normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | inherit",
+ "font-style" : "normal | italic | oblique | inherit",
+ "font-variant" : "normal | small-caps | inherit",
+ "font-weight" : "normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit",
+ "grid-cell-stacking" : "columns | rows | layer",
+ "grid-column" : 1,
+ "grid-columns" : 1,
+ "grid-column-align" : "start | end | center | stretch",
+ "grid-column-sizing" : 1,
+ "grid-column-span" : "<integer>",
+ "grid-flow" : "none | rows | columns",
+ "grid-layer" : "<integer>",
+ "grid-row" : 1,
+ "grid-rows" : 1,
+ "grid-row-align" : "start | end | center | stretch",
+ "grid-row-span" : "<integer>",
+ "grid-row-sizing" : 1,
+ "hanging-punctuation" : 1,
+ "height" : "<margin-width> | inherit",
+ "hyphenate-after" : "<integer> | auto",
+ "hyphenate-before" : "<integer> | auto",
+ "hyphenate-character" : "<string> | auto",
+ "hyphenate-lines" : "no-limit | <integer>",
+ "hyphenate-resource" : 1,
+ "hyphens" : "none | manual | auto",
+ "icon" : 1,
+ "image-orientation" : "angle | auto",
+ "image-rendering" : 1,
+ "image-resolution" : 1,
+ "inline-box-align" : "initial | last | <integer>",
+ "left" : "<margin-width> | inherit",
+ "letter-spacing" : "<length> | normal | inherit",
+ "line-height" : "<number> | <length> | <percentage> | normal | inherit",
+ "line-break" : "auto | loose | normal | strict",
+ "line-stacking" : 1,
+ "line-stacking-ruby" : "exclude-ruby | include-ruby",
+ "line-stacking-shift" : "consider-shifts | disregard-shifts",
+ "line-stacking-strategy" : "inline-line-height | block-line-height | max-height | grid-height",
+ "list-style" : 1,
+ "list-style-image" : "<uri> | none | inherit",
+ "list-style-position" : "inside | outside | inherit",
+ "list-style-type" : "disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none | inherit",
+ "margin" : { multi: "<margin-width> | inherit", max: 4 },
+ "margin-bottom" : "<margin-width> | inherit",
+ "margin-left" : "<margin-width> | inherit",
+ "margin-right" : "<margin-width> | inherit",
+ "margin-top" : "<margin-width> | inherit",
+ "mark" : 1,
+ "mark-after" : 1,
+ "mark-before" : 1,
+ "marks" : 1,
+ "marquee-direction" : 1,
+ "marquee-play-count" : 1,
+ "marquee-speed" : 1,
+ "marquee-style" : 1,
+ "max-height" : "<length> | <percentage> | none | inherit",
+ "max-width" : "<length> | <percentage> | none | inherit",
+ "min-height" : "<length> | <percentage> | inherit",
+ "min-width" : "<length> | <percentage> | inherit",
+ "move-to" : 1,
+ "nav-down" : 1,
+ "nav-index" : 1,
+ "nav-left" : 1,
+ "nav-right" : 1,
+ "nav-up" : 1,
+ "opacity" : "<number> | inherit",
+ "orphans" : "<integer> | inherit",
+ "outline" : 1,
+ "outline-color" : "<color> | invert | inherit",
+ "outline-offset" : 1,
+ "outline-style" : "<border-style> | inherit",
+ "outline-width" : "<border-width> | inherit",
+ "overflow" : "visible | hidden | scroll | auto | inherit",
+ "overflow-style" : 1,
+ "overflow-x" : 1,
+ "overflow-y" : 1,
+ "padding" : { multi: "<padding-width> | inherit", max: 4 },
+ "padding-bottom" : "<padding-width> | inherit",
+ "padding-left" : "<padding-width> | inherit",
+ "padding-right" : "<padding-width> | inherit",
+ "padding-top" : "<padding-width> | inherit",
+ "page" : 1,
+ "page-break-after" : "auto | always | avoid | left | right | inherit",
+ "page-break-before" : "auto | always | avoid | left | right | inherit",
+ "page-break-inside" : "auto | avoid | inherit",
+ "page-policy" : 1,
+ "pause" : 1,
+ "pause-after" : 1,
+ "pause-before" : 1,
+ "perspective" : 1,
+ "perspective-origin" : 1,
+ "phonemes" : 1,
+ "pitch" : 1,
+ "pitch-range" : 1,
+ "play-during" : 1,
+ "pointer-events" : "auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit",
+ "position" : "static | relative | absolute | fixed | inherit",
+ "presentation-level" : 1,
+ "punctuation-trim" : 1,
+ "quotes" : 1,
+ "rendering-intent" : 1,
+ "resize" : 1,
+ "rest" : 1,
+ "rest-after" : 1,
+ "rest-before" : 1,
+ "richness" : 1,
+ "right" : "<margin-width> | inherit",
+ "rotation" : 1,
+ "rotation-point" : 1,
+ "ruby-align" : 1,
+ "ruby-overhang" : 1,
+ "ruby-position" : 1,
+ "ruby-span" : 1,
+ "size" : 1,
+ "speak" : "normal | none | spell-out | inherit",
+ "speak-header" : "once | always | inherit",
+ "speak-numeral" : "digits | continuous | inherit",
+ "speak-punctuation" : "code | none | inherit",
+ "speech-rate" : 1,
+ "src" : 1,
+ "stress" : 1,
+ "string-set" : 1,
+
+ "table-layout" : "auto | fixed | inherit",
+ "tab-size" : "<integer> | <length>",
+ "target" : 1,
+ "target-name" : 1,
+ "target-new" : 1,
+ "target-position" : 1,
+ "text-align" : "left | right | center | justify | inherit" ,
+ "text-align-last" : 1,
+ "text-decoration" : 1,
+ "text-emphasis" : 1,
+ "text-height" : 1,
+ "text-indent" : "<length> | <percentage> | inherit",
+ "text-justify" : "auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida",
+ "text-outline" : 1,
+ "text-overflow" : 1,
+ "text-rendering" : "auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit",
+ "text-shadow" : 1,
+ "text-transform" : "capitalize | uppercase | lowercase | none | inherit",
+ "text-wrap" : "normal | none | avoid",
+ "top" : "<margin-width> | inherit",
+ "transform" : 1,
+ "transform-origin" : 1,
+ "transform-style" : 1,
+ "transition" : 1,
+ "transition-delay" : 1,
+ "transition-duration" : 1,
+ "transition-property" : 1,
+ "transition-timing-function" : 1,
+ "unicode-bidi" : "normal | embed | bidi-override | inherit",
+ "user-modify" : "read-only | read-write | write-only | inherit",
+ "user-select" : "none | text | toggle | element | elements | all | inherit",
+ "vertical-align" : "<percentage> | <length> | baseline | sub | super | top | text-top | middle | bottom | text-bottom | inherit",
+ "visibility" : "visible | hidden | collapse | inherit",
+ "voice-balance" : 1,
+ "voice-duration" : 1,
+ "voice-family" : 1,
+ "voice-pitch" : 1,
+ "voice-pitch-range" : 1,
+ "voice-rate" : 1,
+ "voice-stress" : 1,
+ "voice-volume" : 1,
+ "volume" : 1,
+ "white-space" : "normal | pre | nowrap | pre-wrap | pre-line | inherit",
+ "white-space-collapse" : 1,
+ "widows" : "<integer> | inherit",
+ "width" : "<length> | <percentage> | auto | inherit" ,
+ "word-break" : "normal | keep-all | break-all",
+ "word-spacing" : "<length> | normal | inherit",
+ "word-wrap" : 1,
+ "z-index" : "<integer> | auto | inherit",
+ "zoom" : "<number> | <percentage> | normal"
+};
+function PropertyName(text, hack, line, col){
+
+ SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_NAME_TYPE);
+ this.hack = hack;
+
+}
+
+PropertyName.prototype = new SyntaxUnit();
+PropertyName.prototype.constructor = PropertyName;
+PropertyName.prototype.toString = function(){
+ return (this.hack ? this.hack : "") + this.text;
+};
+function PropertyValue(parts, line, col){
+
+ SyntaxUnit.call(this, parts.join(" "), line, col, Parser.PROPERTY_VALUE_TYPE);
+ this.parts = parts;
+
+}
+
+PropertyValue.prototype = new SyntaxUnit();
+PropertyValue.prototype.constructor = PropertyValue;
+function PropertyValueIterator(value){
+ this._i = 0;
+ this._parts = value.parts;
+ this._marks = [];
+ this.value = value;
+
+}
+PropertyValueIterator.prototype.count = function(){
+ return this._parts.length;
+};
+PropertyValueIterator.prototype.isFirst = function(){
+ return this._i === 0;
+};
+PropertyValueIterator.prototype.hasNext = function(){
+ return (this._i < this._parts.length);
+};
+PropertyValueIterator.prototype.mark = function(){
+ this._marks.push(this._i);
+};
+PropertyValueIterator.prototype.peek = function(count){
+ return this.hasNext() ? this._parts[this._i + (count || 0)] : null;
+};
+PropertyValueIterator.prototype.next = function(){
+ return this.hasNext() ? this._parts[this._i++] : null;
+};
+PropertyValueIterator.prototype.previous = function(){
+ return this._i > 0 ? this._parts[--this._i] : null;
+};
+PropertyValueIterator.prototype.restore = function(){
+ if (this._marks.length){
+ this._i = this._marks.pop();
+ }
+};
+function PropertyValuePart(text, line, col){
+
+ SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_VALUE_PART_TYPE);
+ this.type = "unknown";
+
+ var temp;
+ if (/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)){ //dimension
+ this.type = "dimension";
+ this.value = +RegExp.$1;
+ this.units = RegExp.$2;
+ switch(this.units.toLowerCase()){
+
+ case "em":
+ case "rem":
+ case "ex":
+ case "px":
+ case "cm":
+ case "mm":
+ case "in":
+ case "pt":
+ case "pc":
+ case "ch":
+ this.type = "length";
+ break;
+
+ case "deg":
+ case "rad":
+ case "grad":
+ this.type = "angle";
+ break;
+
+ case "ms":
+ case "s":
+ this.type = "time";
+ break;
+
+ case "hz":
+ case "khz":
+ this.type = "frequency";
+ break;
+
+ case "dpi":
+ case "dpcm":
+ this.type = "resolution";
+ break;
+
+ }
+
+ } else if (/^([+\-]?[\d\.]+)%$/i.test(text)){ //percentage
+ this.type = "percentage";
+ this.value = +RegExp.$1;
+ } else if (/^([+\-]?[\d\.]+)%$/i.test(text)){ //percentage
+ this.type = "percentage";
+ this.value = +RegExp.$1;
+ } else if (/^([+\-]?\d+)$/i.test(text)){ //integer
+ this.type = "integer";
+ this.value = +RegExp.$1;
+ } else if (/^([+\-]?[\d\.]+)$/i.test(text)){ //number
+ this.type = "number";
+ this.value = +RegExp.$1;
+
+ } else if (/^#([a-f0-9]{3,6})/i.test(text)){ //hexcolor
+ this.type = "color";
+ temp = RegExp.$1;
+ if (temp.length == 3){
+ this.red = parseInt(temp.charAt(0)+temp.charAt(0),16);
+ this.green = parseInt(temp.charAt(1)+temp.charAt(1),16);
+ this.blue = parseInt(temp.charAt(2)+temp.charAt(2),16);
+ } else {
+ this.red = parseInt(temp.substring(0,2),16);
+ this.green = parseInt(temp.substring(2,4),16);
+ this.blue = parseInt(temp.substring(4,6),16);
+ }
+ } else if (/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text)){ //rgb() color with absolute numbers
+ this.type = "color";
+ this.red = +RegExp.$1;
+ this.green = +RegExp.$2;
+ this.blue = +RegExp.$3;
+ } else if (/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)){ //rgb() color with percentages
+ this.type = "color";
+ this.red = +RegExp.$1 * 255 / 100;
+ this.green = +RegExp.$2 * 255 / 100;
+ this.blue = +RegExp.$3 * 255 / 100;
+ } else if (/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)){ //rgba() color with absolute numbers
+ this.type = "color";
+ this.red = +RegExp.$1;
+ this.green = +RegExp.$2;
+ this.blue = +RegExp.$3;
+ this.alpha = +RegExp.$4;
+ } else if (/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)){ //rgba() color with percentages
+ this.type = "color";
+ this.red = +RegExp.$1 * 255 / 100;
+ this.green = +RegExp.$2 * 255 / 100;
+ this.blue = +RegExp.$3 * 255 / 100;
+ this.alpha = +RegExp.$4;
+ } else if (/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)){ //hsl()
+ this.type = "color";
+ this.hue = +RegExp.$1;
+ this.saturation = +RegExp.$2 / 100;
+ this.lightness = +RegExp.$3 / 100;
+ } else if (/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)){ //hsla() color with percentages
+ this.type = "color";
+ this.hue = +RegExp.$1;
+ this.saturation = +RegExp.$2 / 100;
+ this.lightness = +RegExp.$3 / 100;
+ this.alpha = +RegExp.$4;
+ } else if (/^url\(["']?([^\)"']+)["']?\)/i.test(text)){ //URI
+ this.type = "uri";
+ this.uri = RegExp.$1;
+ } else if (/^([^\(]+)\(/i.test(text)){
+ this.type = "function";
+ this.name = RegExp.$1;
+ this.value = text;
+ } else if (/^["'][^"']*["']/.test(text)){ //string
+ this.type = "string";
+ this.value = eval(text);
+ } else if (Colors[text.toLowerCase()]){ //named color
+ this.type = "color";
+ temp = Colors[text.toLowerCase()].substring(1);
+ this.red = parseInt(temp.substring(0,2),16);
+ this.green = parseInt(temp.substring(2,4),16);
+ this.blue = parseInt(temp.substring(4,6),16);
+ } else if (/^[\,\/]$/.test(text)){
+ this.type = "operator";
+ this.value = text;
+ } else if (/^[a-z\-\u0080-\uFFFF][a-z0-9\-\u0080-\uFFFF]*$/i.test(text)){
+ this.type = "identifier";
+ this.value = text;
+ }
+
+}
+
+PropertyValuePart.prototype = new SyntaxUnit();
+PropertyValuePart.prototype.constructor = PropertyValuePart;
+PropertyValuePart.fromToken = function(token){
+ return new PropertyValuePart(token.value, token.startLine, token.startCol);
+};
+var Pseudos = {
+ ":first-letter": 1,
+ ":first-line": 1,
+ ":before": 1,
+ ":after": 1
+};
+
+Pseudos.ELEMENT = 1;
+Pseudos.CLASS = 2;
+
+Pseudos.isElement = function(pseudo){
+ return pseudo.indexOf("::") === 0 || Pseudos[pseudo.toLowerCase()] == Pseudos.ELEMENT;
+};
+function Selector(parts, line, col){
+
+ SyntaxUnit.call(this, parts.join(" "), line, col, Parser.SELECTOR_TYPE);
+ this.parts = parts;
+ this.specificity = Specificity.calculate(this);
+
+}
+
+Selector.prototype = new SyntaxUnit();
+Selector.prototype.constructor = Selector;
+function SelectorPart(elementName, modifiers, text, line, col){
+
+ SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_PART_TYPE);
+ this.elementName = elementName;
+ this.modifiers = modifiers;
+
+}
+
+SelectorPart.prototype = new SyntaxUnit();
+SelectorPart.prototype.constructor = SelectorPart;
+function SelectorSubPart(text, type, line, col){
+
+ SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_SUB_PART_TYPE);
+ this.type = type;
+ this.args = [];
+
+}
+
+SelectorSubPart.prototype = new SyntaxUnit();
+SelectorSubPart.prototype.constructor = SelectorSubPart;
+function Specificity(a, b, c, d){
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.d = d;
+}
+
+Specificity.prototype = {
+ constructor: Specificity,
+ compare: function(other){
+ var comps = ["a", "b", "c", "d"],
+ i, len;
+
+ for (i=0, len=comps.length; i < len; i++){
+ if (this[comps[i]] < other[comps[i]]){
+ return -1;
+ } else if (this[comps[i]] > other[comps[i]]){
+ return 1;
+ }
+ }
+
+ return 0;
+ },
+ valueOf: function(){
+ return (this.a * 1000) + (this.b * 100) + (this.c * 10) + this.d;
+ },
+ toString: function(){
+ return this.a + "," + this.b + "," + this.c + "," + this.d;
+ }
+
+};
+Specificity.calculate = function(selector){
+
+ var i, len,
+ part,
+ b=0, c=0, d=0;
+
+ function updateValues(part){
+
+ var i, j, len, num,
+ elementName = part.elementName ? part.elementName.text : "",
+ modifier;
+
+ if (elementName && elementName.charAt(elementName.length-1) != "*") {
+ d++;
+ }
+
+ for (i=0, len=part.modifiers.length; i < len; i++){
+ modifier = part.modifiers[i];
+ switch(modifier.type){
+ case "class":
+ case "attribute":
+ c++;
+ break;
+
+ case "id":
+ b++;
+ break;
+
+ case "pseudo":
+ if (Pseudos.isElement(modifier.text)){
+ d++;
+ } else {
+ c++;
+ }
+ break;
+
+ case "not":
+ for (j=0, num=modifier.args.length; j < num; j++){
+ updateValues(modifier.args[j]);
+ }
+ }
+ }
+ }
+
+ for (i=0, len=selector.parts.length; i < len; i++){
+ part = selector.parts[i];
+
+ if (part instanceof SelectorPart){
+ updateValues(part);
+ }
+ }
+
+ return new Specificity(0, b, c, d);
+};
+
+var h = /^[0-9a-fA-F]$/,
+ nonascii = /^[\u0080-\uFFFF]$/,
+ nl = /\n|\r\n|\r|\f/;
+
+
+function isHexDigit(c){
+ return c !== null && h.test(c);
+}
+
+function isDigit(c){
+ return c !== null && /\d/.test(c);
+}
+
+function isWhitespace(c){
+ return c !== null && /\s/.test(c);
+}
+
+function isNewLine(c){
+ return c !== null && nl.test(c);
+}
+
+function isNameStart(c){
+ return c !== null && (/[a-z_\u0080-\uFFFF\\]/i.test(c));
+}
+
+function isNameChar(c){
+ return c !== null && (isNameStart(c) || /[0-9\-\\]/.test(c));
+}
+
+function isIdentStart(c){
+ return c !== null && (isNameStart(c) || /\-\\/.test(c));
+}
+
+function mix(receiver, supplier){
+ for (var prop in supplier){
+ if (supplier.hasOwnProperty(prop)){
+ receiver[prop] = supplier[prop];
+ }
+ }
+ return receiver;
+}
+function TokenStream(input){
+ TokenStreamBase.call(this, input, Tokens);
+}
+
+TokenStream.prototype = mix(new TokenStreamBase(), {
+ _getToken: function(channel){
+
+ var c,
+ reader = this._reader,
+ token = null,
+ startLine = reader.getLine(),
+ startCol = reader.getCol();
+
+ c = reader.read();
+
+
+ while(c){
+ switch(c){
+ case "/":
+
+ if(reader.peek() == "*"){
+ token = this.commentToken(c, startLine, startCol);
+ } else {
+ token = this.charToken(c, startLine, startCol);
+ }
+ break;
+ case "|":
+ case "~":
+ case "^":
+ case "$":
+ case "*":
+ if(reader.peek() == "="){
+ token = this.comparisonToken(c, startLine, startCol);
+ } else {
+ token = this.charToken(c, startLine, startCol);
+ }
+ break;
+ case "\"":
+ case "'":
+ token = this.stringToken(c, startLine, startCol);
+ break;
+ case "#":
+ if (isNameChar(reader.peek())){
+ token = this.hashToken(c, startLine, startCol);
+ } else {
+ token = this.charToken(c, startLine, startCol);
+ }
+ break;
+ case ".":
+ if (isDigit(reader.peek())){
+ token = this.numberToken(c, startLine, startCol);
+ } else {
+ token = this.charToken(c, startLine, startCol);
+ }
+ break;
+ case "-":
+ if (reader.peek() == "-"){ //could be closing HTML-style comment
+ token = this.htmlCommentEndToken(c, startLine, startCol);
+ } else if (isNameStart(reader.peek())){
+ token = this.identOrFunctionToken(c, startLine, startCol);
+ } else {
+ token = this.charToken(c, startLine, startCol);
+ }
+ break;
+ case "!":
+ token = this.importantToken(c, startLine, startCol);
+ break;
+ case "@":
+ token = this.atRuleToken(c, startLine, startCol);
+ break;
+ case ":":
+ token = this.notToken(c, startLine, startCol);
+ break;
+ case "<":
+ token = this.htmlCommentStartToken(c, startLine, startCol);
+ break;
+ case "U":
+ case "u":
+ if (reader.peek() == "+"){
+ token = this.unicodeRangeToken(c, startLine, startCol);
+ break;
+ }
+ default:
+ if (isDigit(c)){
+ token = this.numberToken(c, startLine, startCol);
+ } else
+ if (isWhitespace(c)){
+ token = this.whitespaceToken(c, startLine, startCol);
+ } else
+ if (isIdentStart(c)){
+ token = this.identOrFunctionToken(c, startLine, startCol);
+ } else
+ {
+ token = this.charToken(c, startLine, startCol);
+ }
+
+
+
+
+
+
+ }
+ break;
+ }
+
+ if (!token && c === null){
+ token = this.createToken(Tokens.EOF,null,startLine,startCol);
+ }
+
+ return token;
+ },
+ createToken: function(tt, value, startLine, startCol, options){
+ var reader = this._reader;
+ options = options || {};
+
+ return {
+ value: value,
+ type: tt,
+ channel: options.channel,
+ hide: options.hide || false,
+ startLine: startLine,
+ startCol: startCol,
+ endLine: reader.getLine(),
+ endCol: reader.getCol()
+ };
+ },
+ atRuleToken: function(first, startLine, startCol){
+ var rule = first,
+ reader = this._reader,
+ tt = Tokens.CHAR,
+ valid = false,
+ ident,
+ c;
+ reader.mark();
+ ident = this.readName();
+ rule = first + ident;
+ tt = Tokens.type(rule.toLowerCase());
+ if (tt == Tokens.CHAR || tt == Tokens.UNKNOWN){
+ if (rule.length > 1){
+ tt = Tokens.UNKNOWN_SYM;
+ } else {
+ tt = Tokens.CHAR;
+ rule = first;
+ reader.reset();
+ }
+ }
+
+ return this.createToken(tt, rule, startLine, startCol);
+ },
+ charToken: function(c, startLine, startCol){
+ var tt = Tokens.type(c);
+
+ if (tt == -1){
+ tt = Tokens.CHAR;
+ }
+
+ return this.createToken(tt, c, startLine, startCol);
+ },
+ commentToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ comment = this.readComment(first);
+
+ return this.createToken(Tokens.COMMENT, comment, startLine, startCol);
+ },
+ comparisonToken: function(c, startLine, startCol){
+ var reader = this._reader,
+ comparison = c + reader.read(),
+ tt = Tokens.type(comparison) || Tokens.CHAR;
+
+ return this.createToken(tt, comparison, startLine, startCol);
+ },
+ hashToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ name = this.readName(first);
+
+ return this.createToken(Tokens.HASH, name, startLine, startCol);
+ },
+ htmlCommentStartToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ text = first;
+
+ reader.mark();
+ text += reader.readCount(3);
+
+ if (text == "<!--"){
+ return this.createToken(Tokens.CDO, text, startLine, startCol);
+ } else {
+ reader.reset();
+ return this.charToken(first, startLine, startCol);
+ }
+ },
+ htmlCommentEndToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ text = first;
+
+ reader.mark();
+ text += reader.readCount(2);
+
+ if (text == "-->"){
+ return this.createToken(Tokens.CDC, text, startLine, startCol);
+ } else {
+ reader.reset();
+ return this.charToken(first, startLine, startCol);
+ }
+ },
+ identOrFunctionToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ ident = this.readName(first),
+ tt = Tokens.IDENT;
+ if (reader.peek() == "("){
+ ident += reader.read();
+ if (ident.toLowerCase() == "url("){
+ tt = Tokens.URI;
+ ident = this.readURI(ident);
+ if (ident.toLowerCase() == "url("){
+ tt = Tokens.FUNCTION;
+ }
+ } else {
+ tt = Tokens.FUNCTION;
+ }
+ } else if (reader.peek() == ":"){ //might be an IE function
+ if (ident.toLowerCase() == "progid"){
+ ident += reader.readTo("(");
+ tt = Tokens.IE_FUNCTION;
+ }
+ }
+
+ return this.createToken(tt, ident, startLine, startCol);
+ },
+ importantToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ important = first,
+ tt = Tokens.CHAR,
+ temp,
+ c;
+
+ reader.mark();
+ c = reader.read();
+
+ while(c){
+ if (c == "/"){
+ if (reader.peek() != "*"){
+ break;
+ } else {
+ temp = this.readComment(c);
+ if (temp === ""){ //broken!
+ break;
+ }
+ }
+ } else if (isWhitespace(c)){
+ important += c + this.readWhitespace();
+ } else if (/i/i.test(c)){
+ temp = reader.readCount(8);
+ if (/mportant/i.test(temp)){
+ important += c + temp;
+ tt = Tokens.IMPORTANT_SYM;
+
+ }
+ break; //we're done
+ } else {
+ break;
+ }
+
+ c = reader.read();
+ }
+
+ if (tt == Tokens.CHAR){
+ reader.reset();
+ return this.charToken(first, startLine, startCol);
+ } else {
+ return this.createToken(tt, important, startLine, startCol);
+ }
+
+
+ },
+ notToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ text = first;
+
+ reader.mark();
+ text += reader.readCount(4);
+
+ if (text.toLowerCase() == ":not("){
+ return this.createToken(Tokens.NOT, text, startLine, startCol);
+ } else {
+ reader.reset();
+ return this.charToken(first, startLine, startCol);
+ }
+ },
+ numberToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ value = this.readNumber(first),
+ ident,
+ tt = Tokens.NUMBER,
+ c = reader.peek();
+
+ if (isIdentStart(c)){
+ ident = this.readName(reader.read());
+ value += ident;
+
+ if (/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^vm$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(ident)){
+ tt = Tokens.LENGTH;
+ } else if (/^deg|^rad$|^grad$/i.test(ident)){
+ tt = Tokens.ANGLE;
+ } else if (/^ms$|^s$/i.test(ident)){
+ tt = Tokens.TIME;
+ } else if (/^hz$|^khz$/i.test(ident)){
+ tt = Tokens.FREQ;
+ } else if (/^dpi$|^dpcm$/i.test(ident)){
+ tt = Tokens.RESOLUTION;
+ } else {
+ tt = Tokens.DIMENSION;
+ }
+
+ } else if (c == "%"){
+ value += reader.read();
+ tt = Tokens.PERCENTAGE;
+ }
+
+ return this.createToken(tt, value, startLine, startCol);
+ },
+ stringToken: function(first, startLine, startCol){
+ var delim = first,
+ string = first,
+ reader = this._reader,
+ prev = first,
+ tt = Tokens.STRING,
+ c = reader.read();
+
+ while(c){
+ string += c;
+ if (c == delim && prev != "\\"){
+ break;
+ }
+ if (isNewLine(reader.peek()) && c != "\\"){
+ tt = Tokens.INVALID;
+ break;
+ }
+ prev = c;
+ c = reader.read();
+ }
+ if (c === null){
+ tt = Tokens.INVALID;
+ }
+
+ return this.createToken(tt, string, startLine, startCol);
+ },
+
+ unicodeRangeToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ value = first,
+ temp,
+ tt = Tokens.CHAR;
+ if (reader.peek() == "+"){
+ reader.mark();
+ value += reader.read();
+ value += this.readUnicodeRangePart(true);
+ if (value.length == 2){
+ reader.reset();
+ } else {
+
+ tt = Tokens.UNICODE_RANGE;
+ if (value.indexOf("?") == -1){
+
+ if (reader.peek() == "-"){
+ reader.mark();
+ temp = reader.read();
+ temp += this.readUnicodeRangePart(false);
+ if (temp.length == 1){
+ reader.reset();
+ } else {
+ value += temp;
+ }
+ }
+
+ }
+ }
+ }
+
+ return this.createToken(tt, value, startLine, startCol);
+ },
+ whitespaceToken: function(first, startLine, startCol){
+ var reader = this._reader,
+ value = first + this.readWhitespace();
+ return this.createToken(Tokens.S, value, startLine, startCol);
+ },
+
+ readUnicodeRangePart: function(allowQuestionMark){
+ var reader = this._reader,
+ part = "",
+ c = reader.peek();
+ while(isHexDigit(c) && part.length < 6){
+ reader.read();
+ part += c;
+ c = reader.peek();
+ }
+ if (allowQuestionMark){
+ while(c == "?" && part.length < 6){
+ reader.read();
+ part += c;
+ c = reader.peek();
+ }
+ }
+
+ return part;
+ },
+
+ readWhitespace: function(){
+ var reader = this._reader,
+ whitespace = "",
+ c = reader.peek();
+
+ while(isWhitespace(c)){
+ reader.read();
+ whitespace += c;
+ c = reader.peek();
+ }
+
+ return whitespace;
+ },
+ readNumber: function(first){
+ var reader = this._reader,
+ number = first,
+ hasDot = (first == "."),
+ c = reader.peek();
+
+
+ while(c){
+ if (isDigit(c)){
+ number += reader.read();
+ } else if (c == "."){
+ if (hasDot){
+ break;
+ } else {
+ hasDot = true;
+ number += reader.read();
+ }
+ } else {
+ break;
+ }
+
+ c = reader.peek();
+ }
+
+ return number;
+ },
+ readString: function(){
+ var reader = this._reader,
+ delim = reader.read(),
+ string = delim,
+ prev = delim,
+ c = reader.peek();
+
+ while(c){
+ c = reader.read();
+ string += c;
+ if (c == delim && prev != "\\"){
+ break;
+ }
+ if (isNewLine(reader.peek()) && c != "\\"){
+ string = "";
+ break;
+ }
+ prev = c;
+ c = reader.peek();
+ }
+ if (c === null){
+ string = "";
+ }
+
+ return string;
+ },
+ readURI: function(first){
+ var reader = this._reader,
+ uri = first,
+ inner = "",
+ c = reader.peek();
+
+ reader.mark();
+ while(c && isWhitespace(c)){
+ reader.read();
+ c = reader.peek();
+ }
+ if (c == "'" || c == "\""){
+ inner = this.readString();
+ } else {
+ inner = this.readURL();
+ }
+
+ c = reader.peek();
+ while(c && isWhitespace(c)){
+ reader.read();
+ c = reader.peek();
+ }
+ if (inner === "" || c != ")"){
+ uri = first;
+ reader.reset();
+ } else {
+ uri += inner + reader.read();
+ }
+
+ return uri;
+ },
+ readURL: function(){
+ var reader = this._reader,
+ url = "",
+ c = reader.peek();
+ while (/^[!#$%&\\*-~]$/.test(c)){
+ url += reader.read();
+ c = reader.peek();
+ }
+
+ return url;
+
+ },
+ readName: function(first){
+ var reader = this._reader,
+ ident = first || "",
+ c = reader.peek();
+
+ while(true){
+ if (c == "\\"){
+ ident += this.readEscape(reader.read());
+ c = reader.peek();
+ } else if(c && isNameChar(c)){
+ ident += reader.read();
+ c = reader.peek();
+ } else {
+ break;
+ }
+ }
+
+ return ident;
+ },
+
+ readEscape: function(first){
+ var reader = this._reader,
+ cssEscape = first || "",
+ i = 0,
+ c = reader.peek();
+
+ if (isHexDigit(c)){
+ do {
+ cssEscape += reader.read();
+ c = reader.peek();
+ } while(c && isHexDigit(c) && ++i < 6);
+ }
+
+ if (cssEscape.length == 3 && /\s/.test(c) ||
+ cssEscape.length == 7 || cssEscape.length == 1){
+ reader.read();
+ } else {
+ c = "";
+ }
+
+ return cssEscape + c;
+ },
+
+ readComment: function(first){
+ var reader = this._reader,
+ comment = first || "",
+ c = reader.read();
+
+ if (c == "*"){
+ while(c){
+ comment += c;
+ if (comment.length > 2 && c == "*" && reader.peek() == "/"){
+ comment += reader.read();
+ break;
+ }
+
+ c = reader.read();
+ }
+
+ return comment;
+ } else {
+ return "";
+ }
+
+ }
+});
+
+
+var Tokens = [
+ { name: "CDO"},
+ { name: "CDC"},
+ { name: "S", whitespace: true/*, channel: "ws"*/},
+ { name: "COMMENT", comment: true, hide: true, channel: "comment" },
+ { name: "INCLUDES", text: "~="},
+ { name: "DASHMATCH", text: "|="},
+ { name: "PREFIXMATCH", text: "^="},
+ { name: "SUFFIXMATCH", text: "$="},
+ { name: "SUBSTRINGMATCH", text: "*="},
+ { name: "STRING"},
+ { name: "IDENT"},
+ { name: "HASH"},
+ { name: "IMPORT_SYM", text: "@import"},
+ { name: "PAGE_SYM", text: "@page"},
+ { name: "MEDIA_SYM", text: "@media"},
+ { name: "FONT_FACE_SYM", text: "@font-face"},
+ { name: "CHARSET_SYM", text: "@charset"},
+ { name: "NAMESPACE_SYM", text: "@namespace"},
+ { name: "UNKNOWN_SYM" },
+ { name: "KEYFRAMES_SYM", text: [ "@keyframes", "@-webkit-keyframes", "@-moz-keyframes", "@-o-keyframes" ] },
+ { name: "IMPORTANT_SYM"},
+ { name: "LENGTH"},
+ { name: "ANGLE"},
+ { name: "TIME"},
+ { name: "FREQ"},
+ { name: "DIMENSION"},
+ { name: "PERCENTAGE"},
+ { name: "NUMBER"},
+ { name: "URI"},
+ { name: "FUNCTION"},
+ { name: "UNICODE_RANGE"},
+ { name: "INVALID"},
+ { name: "PLUS", text: "+" },
+ { name: "GREATER", text: ">"},
+ { name: "COMMA", text: ","},
+ { name: "TILDE", text: "~"},
+ { name: "NOT"},
+ { name: "TOPLEFTCORNER_SYM", text: "@top-left-corner"},
+ { name: "TOPLEFT_SYM", text: "@top-left"},
+ { name: "TOPCENTER_SYM", text: "@top-center"},
+ { name: "TOPRIGHT_SYM", text: "@top-right"},
+ { name: "TOPRIGHTCORNER_SYM", text: "@top-right-corner"},
+ { name: "BOTTOMLEFTCORNER_SYM", text: "@bottom-left-corner"},
+ { name: "BOTTOMLEFT_SYM", text: "@bottom-left"},
+ { name: "BOTTOMCENTER_SYM", text: "@bottom-center"},
+ { name: "BOTTOMRIGHT_SYM", text: "@bottom-right"},
+ { name: "BOTTOMRIGHTCORNER_SYM", text: "@bottom-right-corner"},
+ { name: "LEFTTOP_SYM", text: "@left-top"},
+ { name: "LEFTMIDDLE_SYM", text: "@left-middle"},
+ { name: "LEFTBOTTOM_SYM", text: "@left-bottom"},
+ { name: "RIGHTTOP_SYM", text: "@right-top"},
+ { name: "RIGHTMIDDLE_SYM", text: "@right-middle"},
+ { name: "RIGHTBOTTOM_SYM", text: "@right-bottom"},
+ { name: "RESOLUTION", state: "media"},
+ { name: "IE_FUNCTION" },
+ { name: "CHAR" },
+ {
+ name: "PIPE",
+ text: "|"
+ },
+ {
+ name: "SLASH",
+ text: "/"
+ },
+ {
+ name: "MINUS",
+ text: "-"
+ },
+ {
+ name: "STAR",
+ text: "*"
+ },
+
+ {
+ name: "LBRACE",
+ text: "{"
+ },
+ {
+ name: "RBRACE",
+ text: "}"
+ },
+ {
+ name: "LBRACKET",
+ text: "["
+ },
+ {
+ name: "RBRACKET",
+ text: "]"
+ },
+ {
+ name: "EQUALS",
+ text: "="
+ },
+ {
+ name: "COLON",
+ text: ":"
+ },
+ {
+ name: "SEMICOLON",
+ text: ";"
+ },
+
+ {
+ name: "LPAREN",
+ text: "("
+ },
+ {
+ name: "RPAREN",
+ text: ")"
+ },
+ {
+ name: "DOT",
+ text: "."
+ }
+];
+
+(function(){
+
+ var nameMap = [],
+ typeMap = {};
+
+ Tokens.UNKNOWN = -1;
+ Tokens.unshift({name:"EOF"});
+ for (var i=0, len = Tokens.length; i < len; i++){
+ nameMap.push(Tokens[i].name);
+ Tokens[Tokens[i].name] = i;
+ if (Tokens[i].text){
+ if (Tokens[i].text instanceof Array){
+ for (var j=0; j < Tokens[i].text.length; j++){
+ typeMap[Tokens[i].text[j]] = i;
+ }
+ } else {
+ typeMap[Tokens[i].text] = i;
+ }
+ }
+ }
+
+ Tokens.name = function(tt){
+ return nameMap[tt];
+ };
+
+ Tokens.type = function(c){
+ return typeMap[c] || -1;
+ };
+
+})();
+var Validation = {
+
+ validate: function(property, value){
+ var name = property.toString().toLowerCase(),
+ parts = value.parts,
+ expression = new PropertyValueIterator(value),
+ spec = Properties[name],
+ part,
+ valid,
+ j, count,
+ msg,
+ types,
+ last,
+ literals,
+ max, multi, group;
+
+ if (!spec) {
+ if (name.indexOf("-") !== 0){ //vendor prefixed are ok
+ throw new ValidationError("Unknown property '" + property + "'.", property.line, property.col);
+ }
+ } else if (typeof spec != "number"){
+ if (typeof spec == "string"){
+ if (spec.indexOf("||") > -1) {
+ this.groupProperty(spec, expression);
+ } else {
+ this.singleProperty(spec, expression, 1);
+ }
+
+ } else if (spec.multi) {
+ this.multiProperty(spec.multi, expression, spec.comma, spec.max || Infinity);
+ } else if (typeof spec == "function") {
+ spec(expression);
+ }
+
+ }
+
+ },
+
+ singleProperty: function(types, expression, max, partial) {
+
+ var result = false,
+ value = expression.value,
+ count = 0,
+ part;
+
+ while (expression.hasNext() && count < max) {
+ result = ValidationTypes.isAny(expression, types);
+ if (!result) {
+ break;
+ }
+ count++;
+ }
+
+ if (!result) {
+ if (expression.hasNext() && !expression.isFirst()) {
+ part = expression.peek();
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ } else {
+ throw new ValidationError("Expected (" + types + ") but found '" + value + "'.", value.line, value.col);
+ }
+ } else if (expression.hasNext()) {
+ part = expression.next();
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ }
+
+ },
+
+ multiProperty: function (types, expression, comma, max) {
+
+ var result = false,
+ value = expression.value,
+ count = 0,
+ sep = false,
+ part;
+
+ while(expression.hasNext() && !result && count < max) {
+ if (ValidationTypes.isAny(expression, types)) {
+ count++;
+ if (!expression.hasNext()) {
+ result = true;
+
+ } else if (comma) {
+ if (expression.peek() == ",") {
+ part = expression.next();
+ } else {
+ break;
+ }
+ }
+ } else {
+ break;
+
+ }
+ }
+
+ if (!result) {
+ if (expression.hasNext() && !expression.isFirst()) {
+ part = expression.peek();
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ } else {
+ part = expression.previous();
+ if (comma && part == ",") {
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ } else {
+ throw new ValidationError("Expected (" + types + ") but found '" + value + "'.", value.line, value.col);
+ }
+ }
+
+ } else if (expression.hasNext()) {
+ part = expression.next();
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ }
+
+ },
+
+ groupProperty: function (types, expression, comma) {
+
+ var result = false,
+ value = expression.value,
+ typeCount = types.split("||").length,
+ groups = { count: 0 },
+ partial = false,
+ name,
+ part;
+
+ while(expression.hasNext() && !result) {
+ name = ValidationTypes.isAnyOfGroup(expression, types);
+ if (name) {
+ if (groups[name]) {
+ break;
+ } else {
+ groups[name] = 1;
+ groups.count++;
+ partial = true;
+
+ if (groups.count == typeCount || !expression.hasNext()) {
+ result = true;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (!result) {
+ if (partial && expression.hasNext()) {
+ part = expression.peek();
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ } else {
+ throw new ValidationError("Expected (" + types + ") but found '" + value + "'.", value.line, value.col);
+ }
+ } else if (expression.hasNext()) {
+ part = expression.next();
+ throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
+ }
+ }
+
+
+
+};
+function ValidationError(message, line, col){
+ this.col = col;
+ this.line = line;
+ this.message = message;
+
+}
+ValidationError.prototype = new Error();
+var ValidationTypes = {
+
+ isLiteral: function (part, literals) {
+ var text = part.text.toString().toLowerCase(),
+ args = literals.split(" | "),
+ i, len, found = false;
+
+ for (i=0,len=args.length; i < len && !found; i++){
+ if (text == args[i].toLowerCase()){
+ found = true;
+ }
+ }
+
+ return found;
+ },
+
+ isSimple: function(type) {
+ return !!this.simple[type];
+ },
+
+ isComplex: function(type) {
+ return !!this.complex[type];
+ },
+ isAny: function (expression, types) {
+ var args = types.split(" | "),
+ i, len, found = false;
+
+ for (i=0,len=args.length; i < len && !found && expression.hasNext(); i++){
+ found = this.isType(expression, args[i]);
+ }
+
+ return found;
+ },
+ isAnyOfGroup: function(expression, types) {
+ var args = types.split(" || "),
+ i, len, found = false;
+
+ for (i=0,len=args.length; i < len && !found; i++){
+ found = this.isType(expression, args[i]);
+ }
+
+ return found ? args[i-1] : false;
+ },
+ isType: function (expression, type) {
+ var part = expression.peek(),
+ result = false;
+
+ if (type.charAt(0) != "<") {
+ result = this.isLiteral(part, type);
+ if (result) {
+ expression.next();
+ }
+ } else if (this.simple[type]) {
+ result = this.simple[type](part);
+ if (result) {
+ expression.next();
+ }
+ } else {
+ result = this.complex[type](expression);
+ }
+
+ return result;
+ },
+
+
+
+ simple: {
+
+ "<absolute-size>": function(part){
+ return ValidationTypes.isLiteral(part, "xx-small | x-small | small | medium | large | x-large | xx-large");
+ },
+
+ "<attachment>": function(part){
+ return ValidationTypes.isLiteral(part, "scroll | fixed | local");
+ },
+
+ "<attr>": function(part){
+ return part.type == "function" && part.name == "attr";
+ },
+
+ "<bg-image>": function(part){
+ return this["<image>"](part) || this["<gradient>"](part) || part == "none";
+ },
+
+ "<gradient>": function(part) {
+ return part.type == "function" && /^(?:\-(?:ms|moz|o|webkit)\-)?(?:repeating\-)?(?:radial\-|linear\-)?gradient/i.test(part);
+ },
+
+ "<box>": function(part){
+ return ValidationTypes.isLiteral(part, "padding-box | border-box | content-box");
+ },
+
+ "<content>": function(part){
+ return part.type == "function" && part.name == "content";
+ },
+
+ "<relative-size>": function(part){
+ return ValidationTypes.isLiteral(part, "smaller | larger");
+ },
+ "<ident>": function(part){
+ return part.type == "identifier";
+ },
+
+ "<length>": function(part){
+ return part.type == "length" || part.type == "number" || part.type == "integer" || part == "0";
+ },
+
+ "<color>": function(part){
+ return part.type == "color" || part == "transparent";
+ },
+
+ "<number>": function(part){
+ return part.type == "number" || this["<integer>"](part);
+ },
+
+ "<integer>": function(part){
+ return part.type == "integer";
+ },
+
+ "<line>": function(part){
+ return part.type == "integer";
+ },
+
+ "<angle>": function(part){
+ return part.type == "angle";
+ },
+
+ "<uri>": function(part){
+ return part.type == "uri";
+ },
+
+ "<image>": function(part){
+ return this["<uri>"](part);
+ },
+
+ "<percentage>": function(part){
+ return part.type == "percentage" || part == "0";
+ },
+
+ "<border-width>": function(part){
+ return this["<length>"](part) || ValidationTypes.isLiteral(part, "thin | medium | thick");
+ },
+
+ "<border-style>": function(part){
+ return ValidationTypes.isLiteral(part, "none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset");
+ },
+
+ "<margin-width>": function(part){
+ return this["<length>"](part) || this["<percentage>"](part) || ValidationTypes.isLiteral(part, "auto");
+ },
+
+ "<padding-width>": function(part){
+ return this["<length>"](part) || this["<percentage>"](part);
+ },
+
+ "<shape>": function(part){
+ return part.type == "function" && (part.name == "rect" || part.name == "inset-rect");
+ },
+
+ "<time>": function(part) {
+ return part.type == "time";
+ }
+ },
+
+ complex: {
+
+ "<bg-position>": function(expression){
+ var types = this,
+ result = false,
+ numeric = "<percentage> | <length>",
+ xDir = "left | center | right",
+ yDir = "top | center | bottom",
+ part,
+ i, len;
+
+ if (ValidationTypes.isAny(expression, "top | bottom")) {
+ result = true;
+ } else {
+ if (ValidationTypes.isAny(expression, numeric)){
+ if (expression.hasNext()){
+ result = ValidationTypes.isAny(expression, numeric + " | " + yDir);
+ }
+ } else if (ValidationTypes.isAny(expression, xDir)){
+ if (expression.hasNext()){
+ if (ValidationTypes.isAny(expression, yDir)){
+ result = true;
+
+ ValidationTypes.isAny(expression, numeric);
+
+ } else if (ValidationTypes.isAny(expression, numeric)){
+ if (ValidationTypes.isAny(expression, yDir)){
+ ValidationTypes.isAny(expression, numeric);
+ }
+
+ result = true;
+ }
+ }
+ }
+ }
+
+
+ return result;
+ },
+
+ "<bg-size>": function(expression){
+ var types = this,
+ result = false,
+ numeric = "<percentage> | <length> | auto",
+ part,
+ i, len;
+
+ if (ValidationTypes.isAny(expression, "cover | contain")) {
+ result = true;
+ } else if (ValidationTypes.isAny(expression, numeric)) {
+ result = true;
+ ValidationTypes.isAny(expression, numeric);
+ }
+
+ return result;
+ },
+
+ "<repeat-style>": function(expression){
+ var result = false,
+ values = "repeat | space | round | no-repeat",
+ part;
+
+ if (expression.hasNext()){
+ part = expression.next();
+
+ if (ValidationTypes.isLiteral(part, "repeat-x | repeat-y")) {
+ result = true;
+ } else if (ValidationTypes.isLiteral(part, values)) {
+ result = true;
+
+ if (expression.hasNext() && ValidationTypes.isLiteral(expression.peek(), values)) {
+ expression.next();
+ }
+ }
+ }
+
+ return result;
+
+ },
+
+ "<shadow>": function(expression) {
+ var result = false,
+ count = 0,
+ inset = false,
+ color = false,
+ part;
+
+ if (expression.hasNext()) {
+
+ if (ValidationTypes.isAny(expression, "inset")){
+ inset = true;
+ }
+
+ if (ValidationTypes.isAny(expression, "<color>")) {
+ color = true;
+ }
+
+ while (ValidationTypes.isAny(expression, "<length>") && count < 4) {
+ count++;
+ }
+
+
+ if (expression.hasNext()) {
+ if (!color) {
+ ValidationTypes.isAny(expression, "<color>");
+ }
+
+ if (!inset) {
+ ValidationTypes.isAny(expression, "inset");
+ }
+
+ }
+
+ result = (count >= 2 && count <= 4);
+
+ }
+
+ return result;
+ },
+
+ "<x-one-radius>": function(expression) {
+ var result = false,
+ count = 0,
+ numeric = "<length> | <percentage>",
+ part;
+
+ if (ValidationTypes.isAny(expression, numeric)){
+ result = true;
+
+ ValidationTypes.isAny(expression, numeric);
+ }
+
+ return result;
+ }
+ }
+};
+
+
+parserlib.css = {
+Colors :Colors,
+Combinator :Combinator,
+Parser :Parser,
+PropertyName :PropertyName,
+PropertyValue :PropertyValue,
+PropertyValuePart :PropertyValuePart,
+MediaFeature :MediaFeature,
+MediaQuery :MediaQuery,
+Selector :Selector,
+SelectorPart :SelectorPart,
+SelectorSubPart :SelectorSubPart,
+Specificity :Specificity,
+TokenStream :TokenStream,
+Tokens :Tokens,
+ValidationError :ValidationError
+};
+})();
+var CSSLint = (function(){
+
+ var rules = [],
+ formatters = [],
+ api = new parserlib.util.EventTarget();
+
+ api.version = "0.9.9";
+ api.addRule = function(rule){
+ rules.push(rule);
+ rules[rule.id] = rule;
+ };
+ api.clearRules = function(){
+ rules = [];
+ };
+ api.getRules = function(){
+ return [].concat(rules).sort(function(a,b){
+ return a.id > b.id ? 1 : 0;
+ });
+ };
+ api.getRuleset = function() {
+ var ruleset = {},
+ i = 0,
+ len = rules.length;
+
+ while (i < len){
+ ruleset[rules[i++].id] = 1; //by default, everything is a warning
+ }
+
+ return ruleset;
+ };
+ api.addFormatter = function(formatter) {
+ formatters[formatter.id] = formatter;
+ };
+ api.getFormatter = function(formatId){
+ return formatters[formatId];
+ };
+ api.format = function(results, filename, formatId, options) {
+ var formatter = this.getFormatter(formatId),
+ result = null;
+
+ if (formatter){
+ result = formatter.startFormat();
+ result += formatter.formatResults(results, filename, options || {});
+ result += formatter.endFormat();
+ }
+
+ return result;
+ };
+ api.hasFormat = function(formatId){
+ return formatters.hasOwnProperty(formatId);
+ };
+ api.verify = function(text, ruleset){
+
+ var i = 0,
+ len = rules.length,
+ reporter,
+ lines,
+ report,
+ parser = new parserlib.css.Parser({ starHack: true, ieFilters: true,
+ underscoreHack: true, strict: false });
+ lines = text.replace(/\n\r?/g, "$split$").split('$split$');
+
+ if (!ruleset){
+ ruleset = this.getRuleset();
+ }
+
+ reporter = new Reporter(lines, ruleset);
+
+ ruleset.errors = 2; //always report parsing errors as errors
+ for (i in ruleset){
+ if(ruleset.hasOwnProperty(i)){
+ if (rules[i]){
+ rules[i].init(parser, reporter);
+ }
+ }
+ }
+ try {
+ parser.parse(text);
+ } catch (ex) {
+ reporter.error("Fatal error, cannot continue: " + ex.message, ex.line, ex.col, {});
+ }
+
+ report = {
+ messages : reporter.messages,
+ stats : reporter.stats
+ };
+ report.messages.sort(function (a, b){
+ if (a.rollup && !b.rollup){
+ return 1;
+ } else if (!a.rollup && b.rollup){
+ return -1;
+ } else {
+ return a.line - b.line;
+ }
+ });
+
+ return report;
+ };
+
+ return api;
+
+})();
+function Reporter(lines, ruleset){
+ this.messages = [];
+ this.stats = [];
+ this.lines = lines;
+ this.ruleset = ruleset;
+}
+
+Reporter.prototype = {
+ constructor: Reporter,
+ error: function(message, line, col, rule){
+ this.messages.push({
+ type : "error",
+ line : line,
+ col : col,
+ message : message,
+ evidence: this.lines[line-1],
+ rule : rule || {}
+ });
+ },
+ warn: function(message, line, col, rule){
+ this.report(message, line, col, rule);
+ },
+ report: function(message, line, col, rule){
+ this.messages.push({
+ type : this.ruleset[rule.id] == 2 ? "error" : "warning",
+ line : line,
+ col : col,
+ message : message,
+ evidence: this.lines[line-1],
+ rule : rule
+ });
+ },
+ info: function(message, line, col, rule){
+ this.messages.push({
+ type : "info",
+ line : line,
+ col : col,
+ message : message,
+ evidence: this.lines[line-1],
+ rule : rule
+ });
+ },
+ rollupError: function(message, rule){
+ this.messages.push({
+ type : "error",
+ rollup : true,
+ message : message,
+ rule : rule
+ });
+ },
+ rollupWarn: function(message, rule){
+ this.messages.push({
+ type : "warning",
+ rollup : true,
+ message : message,
+ rule : rule
+ });
+ },
+ stat: function(name, value){
+ this.stats[name] = value;
+ }
+};
+CSSLint._Reporter = Reporter;
+CSSLint.Util = {
+ mix: function(receiver, supplier){
+ var prop;
+
+ for (prop in supplier){
+ if (supplier.hasOwnProperty(prop)){
+ receiver[prop] = supplier[prop];
+ }
+ }
+
+ return prop;
+ },
+ indexOf: function(values, value){
+ if (values.indexOf){
+ return values.indexOf(value);
+ } else {
+ for (var i=0, len=values.length; i < len; i++){
+ if (values[i] === value){
+ return i;
+ }
+ }
+ return -1;
+ }
+ },
+ forEach: function(values, func) {
+ if (values.forEach){
+ return values.forEach(func);
+ } else {
+ for (var i=0, len=values.length; i < len; i++){
+ func(values[i], i, values);
+ }
+ }
+ }
+};
+CSSLint.addRule({
+ id: "adjoining-classes",
+ name: "Disallow adjoining classes",
+ desc: "Don't use adjoining classes.",
+ browsers: "IE6",
+ init: function(parser, reporter){
+ var rule = this;
+ parser.addListener("startrule", function(event){
+ var selectors = event.selectors,
+ selector,
+ part,
+ modifier,
+ classCount,
+ i, j, k;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+ for (j=0; j < selector.parts.length; j++){
+ part = selector.parts[j];
+ if (part.type == parser.SELECTOR_PART_TYPE){
+ classCount = 0;
+ for (k=0; k < part.modifiers.length; k++){
+ modifier = part.modifiers[k];
+ if (modifier.type == "class"){
+ classCount++;
+ }
+ if (classCount > 1){
+ reporter.report("Don't use adjoining classes.", part.line, part.col, rule);
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "box-model",
+ name: "Beware of broken box size",
+ desc: "Don't use width or height when using padding or border.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ widthProperties = {
+ border: 1,
+ "border-left": 1,
+ "border-right": 1,
+ padding: 1,
+ "padding-left": 1,
+ "padding-right": 1
+ },
+ heightProperties = {
+ border: 1,
+ "border-bottom": 1,
+ "border-top": 1,
+ padding: 1,
+ "padding-bottom": 1,
+ "padding-top": 1
+ },
+ properties,
+ boxSizing = false;
+
+ function startRule(){
+ properties = {};
+ boxSizing = false;
+ }
+
+ function endRule(){
+ var prop, value;
+
+ if (!boxSizing) {
+ if (properties.height){
+ for (prop in heightProperties){
+ if (heightProperties.hasOwnProperty(prop) && properties[prop]){
+ value = properties[prop].value;
+ if (!(prop == "padding" && value.parts.length === 2 && value.parts[0].value === 0)){
+ reporter.report("Using height with " + prop + " can sometimes make elements larger than you expect.", properties[prop].line, properties[prop].col, rule);
+ }
+ }
+ }
+ }
+
+ if (properties.width){
+ for (prop in widthProperties){
+ if (widthProperties.hasOwnProperty(prop) && properties[prop]){
+ value = properties[prop].value;
+
+ if (!(prop == "padding" && value.parts.length === 2 && value.parts[1].value === 0)){
+ reporter.report("Using width with " + prop + " can sometimes make elements larger than you expect.", properties[prop].line, properties[prop].col, rule);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ parser.addListener("startrule", startRule);
+ parser.addListener("startfontface", startRule);
+ parser.addListener("startpage", startRule);
+ parser.addListener("startpagemargin", startRule);
+ parser.addListener("startkeyframerule", startRule);
+
+ parser.addListener("property", function(event){
+ var name = event.property.text.toLowerCase();
+
+ if (heightProperties[name] || widthProperties[name]){
+ if (!/^0\S*$/.test(event.value) && !(name == "border" && event.value == "none")){
+ properties[name] = { line: event.property.line, col: event.property.col, value: event.value };
+ }
+ } else {
+ if (/^(width|height)/i.test(name) && /^(length|percentage)/.test(event.value.parts[0].type)){
+ properties[name] = 1;
+ } else if (name == "box-sizing") {
+ boxSizing = true;
+ }
+ }
+
+ });
+
+ parser.addListener("endrule", endRule);
+ parser.addListener("endfontface", endRule);
+ parser.addListener("endpage", endRule);
+ parser.addListener("endpagemargin", endRule);
+ parser.addListener("endkeyframerule", endRule);
+ }
+
+});
+CSSLint.addRule({
+ id: "box-sizing",
+ name: "Disallow use of box-sizing",
+ desc: "The box-sizing properties isn't supported in IE6 and IE7.",
+ browsers: "IE6, IE7",
+ tags: ["Compatibility"],
+ init: function(parser, reporter){
+ var rule = this;
+
+ parser.addListener("property", function(event){
+ var name = event.property.text.toLowerCase();
+
+ if (name == "box-sizing"){
+ reporter.report("The box-sizing property isn't supported in IE6 and IE7.", event.line, event.col, rule);
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "compatible-vendor-prefixes",
+ name: "Require compatible vendor prefixes",
+ desc: "Include all compatible vendor prefixes to reach a wider range of users.",
+ browsers: "All",
+ init: function (parser, reporter) {
+ var rule = this,
+ compatiblePrefixes,
+ properties,
+ prop,
+ variations,
+ prefixed,
+ i,
+ len,
+ inKeyFrame = false,
+ arrayPush = Array.prototype.push,
+ applyTo = [];
+ compatiblePrefixes = {
+ "animation" : "webkit moz",
+ "animation-delay" : "webkit moz",
+ "animation-direction" : "webkit moz",
+ "animation-duration" : "webkit moz",
+ "animation-fill-mode" : "webkit moz",
+ "animation-iteration-count" : "webkit moz",
+ "animation-name" : "webkit moz",
+ "animation-play-state" : "webkit moz",
+ "animation-timing-function" : "webkit moz",
+ "appearance" : "webkit moz",
+ "border-end" : "webkit moz",
+ "border-end-color" : "webkit moz",
+ "border-end-style" : "webkit moz",
+ "border-end-width" : "webkit moz",
+ "border-image" : "webkit moz o",
+ "border-radius" : "webkit moz",
+ "border-start" : "webkit moz",
+ "border-start-color" : "webkit moz",
+ "border-start-style" : "webkit moz",
+ "border-start-width" : "webkit moz",
+ "box-align" : "webkit moz ms",
+ "box-direction" : "webkit moz ms",
+ "box-flex" : "webkit moz ms",
+ "box-lines" : "webkit ms",
+ "box-ordinal-group" : "webkit moz ms",
+ "box-orient" : "webkit moz ms",
+ "box-pack" : "webkit moz ms",
+ "box-sizing" : "webkit moz",
+ "box-shadow" : "webkit moz",
+ "column-count" : "webkit moz ms",
+ "column-gap" : "webkit moz ms",
+ "column-rule" : "webkit moz ms",
+ "column-rule-color" : "webkit moz ms",
+ "column-rule-style" : "webkit moz ms",
+ "column-rule-width" : "webkit moz ms",
+ "column-width" : "webkit moz ms",
+ "hyphens" : "epub moz",
+ "line-break" : "webkit ms",
+ "margin-end" : "webkit moz",
+ "margin-start" : "webkit moz",
+ "marquee-speed" : "webkit wap",
+ "marquee-style" : "webkit wap",
+ "padding-end" : "webkit moz",
+ "padding-start" : "webkit moz",
+ "tab-size" : "moz o",
+ "text-size-adjust" : "webkit ms",
+ "transform" : "webkit moz ms o",
+ "transform-origin" : "webkit moz ms o",
+ "transition" : "webkit moz o",
+ "transition-delay" : "webkit moz o",
+ "transition-duration" : "webkit moz o",
+ "transition-property" : "webkit moz o",
+ "transition-timing-function" : "webkit moz o",
+ "user-modify" : "webkit moz",
+ "user-select" : "webkit moz ms",
+ "word-break" : "epub ms",
+ "writing-mode" : "epub ms"
+ };
+
+
+ for (prop in compatiblePrefixes) {
+ if (compatiblePrefixes.hasOwnProperty(prop)) {
+ variations = [];
+ prefixed = compatiblePrefixes[prop].split(' ');
+ for (i = 0, len = prefixed.length; i < len; i++) {
+ variations.push('-' + prefixed[i] + '-' + prop);
+ }
+ compatiblePrefixes[prop] = variations;
+ arrayPush.apply(applyTo, variations);
+ }
+ }
+
+ parser.addListener("startrule", function () {
+ properties = [];
+ });
+
+ parser.addListener("startkeyframes", function (event) {
+ inKeyFrame = event.prefix || true;
+ });
+
+ parser.addListener("endkeyframes", function (event) {
+ inKeyFrame = false;
+ });
+
+ parser.addListener("property", function (event) {
+ var name = event.property;
+ if (CSSLint.Util.indexOf(applyTo, name.text) > -1) {
+ if (!inKeyFrame || typeof inKeyFrame != "string" ||
+ name.text.indexOf("-" + inKeyFrame + "-") !== 0) {
+ properties.push(name);
+ }
+ }
+ });
+
+ parser.addListener("endrule", function (event) {
+ if (!properties.length) {
+ return;
+ }
+
+ var propertyGroups = {},
+ i,
+ len,
+ name,
+ prop,
+ variations,
+ value,
+ full,
+ actual,
+ item,
+ propertiesSpecified;
+
+ for (i = 0, len = properties.length; i < len; i++) {
+ name = properties[i];
+
+ for (prop in compatiblePrefixes) {
+ if (compatiblePrefixes.hasOwnProperty(prop)) {
+ variations = compatiblePrefixes[prop];
+ if (CSSLint.Util.indexOf(variations, name.text) > -1) {
+ if (!propertyGroups[prop]) {
+ propertyGroups[prop] = {
+ full : variations.slice(0),
+ actual : [],
+ actualNodes: []
+ };
+ }
+ if (CSSLint.Util.indexOf(propertyGroups[prop].actual, name.text) === -1) {
+ propertyGroups[prop].actual.push(name.text);
+ propertyGroups[prop].actualNodes.push(name);
+ }
+ }
+ }
+ }
+ }
+
+ for (prop in propertyGroups) {
+ if (propertyGroups.hasOwnProperty(prop)) {
+ value = propertyGroups[prop];
+ full = value.full;
+ actual = value.actual;
+
+ if (full.length > actual.length) {
+ for (i = 0, len = full.length; i < len; i++) {
+ item = full[i];
+ if (CSSLint.Util.indexOf(actual, item) === -1) {
+ propertiesSpecified = (actual.length === 1) ? actual[0] : (actual.length == 2) ? actual.join(" and ") : actual.join(", ");
+ reporter.report("The property " + item + " is compatible with " + propertiesSpecified + " and should be included as well.", value.actualNodes[0].line, value.actualNodes[0].col, rule);
+ }
+ }
+
+ }
+ }
+ }
+ });
+ }
+});
+CSSLint.addRule({
+ id: "display-property-grouping",
+ name: "Require properties appropriate for display",
+ desc: "Certain properties shouldn't be used with certain display property values.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ var propertiesToCheck = {
+ display: 1,
+ "float": "none",
+ height: 1,
+ width: 1,
+ margin: 1,
+ "margin-left": 1,
+ "margin-right": 1,
+ "margin-bottom": 1,
+ "margin-top": 1,
+ padding: 1,
+ "padding-left": 1,
+ "padding-right": 1,
+ "padding-bottom": 1,
+ "padding-top": 1,
+ "vertical-align": 1
+ },
+ properties;
+
+ function reportProperty(name, display, msg){
+ if (properties[name]){
+ if (typeof propertiesToCheck[name] != "string" || properties[name].value.toLowerCase() != propertiesToCheck[name]){
+ reporter.report(msg || name + " can't be used with display: " + display + ".", properties[name].line, properties[name].col, rule);
+ }
+ }
+ }
+
+ function startRule(){
+ properties = {};
+ }
+
+ function endRule(){
+
+ var display = properties.display ? properties.display.value : null;
+ if (display){
+ switch(display){
+
+ case "inline":
+ reportProperty("height", display);
+ reportProperty("width", display);
+ reportProperty("margin", display);
+ reportProperty("margin-top", display);
+ reportProperty("margin-bottom", display);
+ reportProperty("float", display, "display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug).");
+ break;
+
+ case "block":
+ reportProperty("vertical-align", display);
+ break;
+
+ case "inline-block":
+ reportProperty("float", display);
+ break;
+
+ default:
+ if (display.indexOf("table-") === 0){
+ reportProperty("margin", display);
+ reportProperty("margin-left", display);
+ reportProperty("margin-right", display);
+ reportProperty("margin-top", display);
+ reportProperty("margin-bottom", display);
+ reportProperty("float", display);
+ }
+ }
+ }
+
+ }
+
+ parser.addListener("startrule", startRule);
+ parser.addListener("startfontface", startRule);
+ parser.addListener("startkeyframerule", startRule);
+ parser.addListener("startpagemargin", startRule);
+ parser.addListener("startpage", startRule);
+
+ parser.addListener("property", function(event){
+ var name = event.property.text.toLowerCase();
+
+ if (propertiesToCheck[name]){
+ properties[name] = { value: event.value.text, line: event.property.line, col: event.property.col };
+ }
+ });
+
+ parser.addListener("endrule", endRule);
+ parser.addListener("endfontface", endRule);
+ parser.addListener("endkeyframerule", endRule);
+ parser.addListener("endpagemargin", endRule);
+ parser.addListener("endpage", endRule);
+
+ }
+
+});
+CSSLint.addRule({
+ id: "duplicate-background-images",
+ name: "Disallow duplicate background images",
+ desc: "Every background-image should be unique. Use a common class for e.g. sprites.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ stack = {};
+
+ parser.addListener("property", function(event){
+ var name = event.property.text,
+ value = event.value,
+ i, len;
+
+ if (name.match(/background/i)) {
+ for (i=0, len=value.parts.length; i < len; i++) {
+ if (value.parts[i].type == 'uri') {
+ if (typeof stack[value.parts[i].uri] === 'undefined') {
+ stack[value.parts[i].uri] = event;
+ }
+ else {
+ reporter.report("Background image '" + value.parts[i].uri + "' was used multiple times, first declared at line " + stack[value.parts[i].uri].line + ", col " + stack[value.parts[i].uri].col + ".", event.line, event.col, rule);
+ }
+ }
+ }
+ }
+ });
+ }
+});
+CSSLint.addRule({
+ id: "duplicate-properties",
+ name: "Disallow duplicate properties",
+ desc: "Duplicate properties must appear one after the other.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ properties,
+ lastProperty;
+
+ function startRule(event){
+ properties = {};
+ }
+
+ parser.addListener("startrule", startRule);
+ parser.addListener("startfontface", startRule);
+ parser.addListener("startpage", startRule);
+ parser.addListener("startpagemargin", startRule);
+ parser.addListener("startkeyframerule", startRule);
+
+ parser.addListener("property", function(event){
+ var property = event.property,
+ name = property.text.toLowerCase();
+
+ if (properties[name] && (lastProperty != name || properties[name] == event.value.text)){
+ reporter.report("Duplicate property '" + event.property + "' found.", event.line, event.col, rule);
+ }
+
+ properties[name] = event.value.text;
+ lastProperty = name;
+
+ });
+
+
+ }
+
+});
+CSSLint.addRule({
+ id: "empty-rules",
+ name: "Disallow empty rules",
+ desc: "Rules without any properties specified should be removed.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ count = 0;
+
+ parser.addListener("startrule", function(){
+ count=0;
+ });
+
+ parser.addListener("property", function(){
+ count++;
+ });
+
+ parser.addListener("endrule", function(event){
+ var selectors = event.selectors;
+ if (count === 0){
+ reporter.report("Rule is empty.", selectors[0].line, selectors[0].col, rule);
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "errors",
+ name: "Parsing Errors",
+ desc: "This rule looks for recoverable syntax errors.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ parser.addListener("error", function(event){
+ reporter.error(event.message, event.line, event.col, rule);
+ });
+
+ }
+
+});
+CSSLint.addRule({
+ id: "fallback-colors",
+ name: "Require fallback colors",
+ desc: "For older browsers that don't support RGBA, HSL, or HSLA, provide a fallback color.",
+ browsers: "IE6,IE7,IE8",
+ init: function(parser, reporter){
+ var rule = this,
+ lastProperty,
+ propertiesToCheck = {
+ color: 1,
+ background: 1,
+ "background-color": 1
+ },
+ properties;
+
+ function startRule(event){
+ properties = {};
+ lastProperty = null;
+ }
+
+ parser.addListener("startrule", startRule);
+ parser.addListener("startfontface", startRule);
+ parser.addListener("startpage", startRule);
+ parser.addListener("startpagemargin", startRule);
+ parser.addListener("startkeyframerule", startRule);
+
+ parser.addListener("property", function(event){
+ var property = event.property,
+ name = property.text.toLowerCase(),
+ parts = event.value.parts,
+ i = 0,
+ colorType = "",
+ len = parts.length;
+
+ if(propertiesToCheck[name]){
+ while(i < len){
+ if (parts[i].type == "color"){
+ if ("alpha" in parts[i] || "hue" in parts[i]){
+
+ if (/([^\)]+)\(/.test(parts[i])){
+ colorType = RegExp.$1.toUpperCase();
+ }
+
+ if (!lastProperty || (lastProperty.property.text.toLowerCase() != name || lastProperty.colorType != "compat")){
+ reporter.report("Fallback " + name + " (hex or RGB) should precede " + colorType + " " + name + ".", event.line, event.col, rule);
+ }
+ } else {
+ event.colorType = "compat";
+ }
+ }
+
+ i++;
+ }
+ }
+
+ lastProperty = event;
+ });
+
+ }
+
+});
+CSSLint.addRule({
+ id: "floats",
+ name: "Disallow too many floats",
+ desc: "This rule tests if the float property is used too many times",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+ var count = 0;
+ parser.addListener("property", function(event){
+ if (event.property.text.toLowerCase() == "float" &&
+ event.value.text.toLowerCase() != "none"){
+ count++;
+ }
+ });
+ parser.addListener("endstylesheet", function(){
+ reporter.stat("floats", count);
+ if (count >= 10){
+ reporter.rollupWarn("Too many floats (" + count + "), you're probably using them for layout. Consider using a grid system instead.", rule);
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "font-faces",
+ name: "Don't use too many web fonts",
+ desc: "Too many different web fonts in the same stylesheet.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ count = 0;
+
+
+ parser.addListener("startfontface", function(){
+ count++;
+ });
+
+ parser.addListener("endstylesheet", function(){
+ if (count > 5){
+ reporter.rollupWarn("Too many @font-face declarations (" + count + ").", rule);
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "font-sizes",
+ name: "Disallow too many font sizes",
+ desc: "Checks the number of font-size declarations.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ count = 0;
+ parser.addListener("property", function(event){
+ if (event.property == "font-size"){
+ count++;
+ }
+ });
+ parser.addListener("endstylesheet", function(){
+ reporter.stat("font-sizes", count);
+ if (count >= 10){
+ reporter.rollupWarn("Too many font-size declarations (" + count + "), abstraction needed.", rule);
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "gradients",
+ name: "Require all gradient definitions",
+ desc: "When using a vendor-prefixed gradient, make sure to use them all.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ gradients;
+
+ parser.addListener("startrule", function(){
+ gradients = {
+ moz: 0,
+ webkit: 0,
+ oldWebkit: 0,
+ ms: 0,
+ o: 0
+ };
+ });
+
+ parser.addListener("property", function(event){
+
+ if (/\-(moz|ms|o|webkit)(?:\-(?:linear|radial))\-gradient/i.test(event.value)){
+ gradients[RegExp.$1] = 1;
+ } else if (/\-webkit\-gradient/i.test(event.value)){
+ gradients.oldWebkit = 1;
+ }
+
+ });
+
+ parser.addListener("endrule", function(event){
+ var missing = [];
+
+ if (!gradients.moz){
+ missing.push("Firefox 3.6+");
+ }
+
+ if (!gradients.webkit){
+ missing.push("Webkit (Safari 5+, Chrome)");
+ }
+
+ if (!gradients.oldWebkit){
+ missing.push("Old Webkit (Safari 4+, Chrome)");
+ }
+
+ if (!gradients.ms){
+ missing.push("Internet Explorer 10+");
+ }
+
+ if (!gradients.o){
+ missing.push("Opera 11.1+");
+ }
+
+ if (missing.length && missing.length < 5){
+ reporter.report("Missing vendor-prefixed CSS gradients for " + missing.join(", ") + ".", event.selectors[0].line, event.selectors[0].col, rule);
+ }
+
+ });
+
+ }
+
+});
+CSSLint.addRule({
+ id: "ids",
+ name: "Disallow IDs in selectors",
+ desc: "Selectors should not contain IDs.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+ parser.addListener("startrule", function(event){
+ var selectors = event.selectors,
+ selector,
+ part,
+ modifier,
+ idCount,
+ i, j, k;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+ idCount = 0;
+
+ for (j=0; j < selector.parts.length; j++){
+ part = selector.parts[j];
+ if (part.type == parser.SELECTOR_PART_TYPE){
+ for (k=0; k < part.modifiers.length; k++){
+ modifier = part.modifiers[k];
+ if (modifier.type == "id"){
+ idCount++;
+ }
+ }
+ }
+ }
+
+ if (idCount == 1){
+ reporter.report("Don't use IDs in selectors.", selector.line, selector.col, rule);
+ } else if (idCount > 1){
+ reporter.report(idCount + " IDs in the selector, really?", selector.line, selector.col, rule);
+ }
+ }
+
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "import",
+ name: "Disallow @import",
+ desc: "Don't use @import, use <link> instead.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ parser.addListener("import", function(event){
+ reporter.report("@import prevents parallel downloads, use <link> instead.", event.line, event.col, rule);
+ });
+
+ }
+
+});
+CSSLint.addRule({
+ id: "important",
+ name: "Disallow !important",
+ desc: "Be careful when using !important declaration",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ count = 0;
+ parser.addListener("property", function(event){
+ if (event.important === true){
+ count++;
+ reporter.report("Be careful when using !important declaration", event.line, event.col, rule);
+ }
+ });
+ parser.addListener("endstylesheet", function(){
+ reporter.stat("important", count);
+ if (count >= 10){
+ reporter.rollupWarn("Too many !important declarations (" + count + "), try to use less than 10 to avoid specificity issues.", rule);
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "known-properties",
+ name: "Require use of known properties",
+ desc: "Properties should be known (listed in CSS3 specification) or be a vendor-prefixed property.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ parser.addListener("property", function(event){
+ var name = event.property.text.toLowerCase();
+ if (event.invalid) {
+ reporter.report(event.invalid.message, event.line, event.col, rule);
+ }
+
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "outline-none",
+ name: "Disallow outline: none",
+ desc: "Use of outline: none or outline: 0 should be limited to :focus rules.",
+ browsers: "All",
+ tags: ["Accessibility"],
+ init: function(parser, reporter){
+ var rule = this,
+ lastRule;
+
+ function startRule(event){
+ if (event.selectors){
+ lastRule = {
+ line: event.line,
+ col: event.col,
+ selectors: event.selectors,
+ propCount: 0,
+ outline: false
+ };
+ } else {
+ lastRule = null;
+ }
+ }
+
+ function endRule(event){
+ if (lastRule){
+ if (lastRule.outline){
+ if (lastRule.selectors.toString().toLowerCase().indexOf(":focus") == -1){
+ reporter.report("Outlines should only be modified using :focus.", lastRule.line, lastRule.col, rule);
+ } else if (lastRule.propCount == 1) {
+ reporter.report("Outlines shouldn't be hidden unless other visual changes are made.", lastRule.line, lastRule.col, rule);
+ }
+ }
+ }
+ }
+
+ parser.addListener("startrule", startRule);
+ parser.addListener("startfontface", startRule);
+ parser.addListener("startpage", startRule);
+ parser.addListener("startpagemargin", startRule);
+ parser.addListener("startkeyframerule", startRule);
+
+ parser.addListener("property", function(event){
+ var name = event.property.text.toLowerCase(),
+ value = event.value;
+
+ if (lastRule){
+ lastRule.propCount++;
+ if (name == "outline" && (value == "none" || value == "0")){
+ lastRule.outline = true;
+ }
+ }
+
+ });
+
+ parser.addListener("endrule", endRule);
+ parser.addListener("endfontface", endRule);
+ parser.addListener("endpage", endRule);
+ parser.addListener("endpagemargin", endRule);
+ parser.addListener("endkeyframerule", endRule);
+
+ }
+
+});
+CSSLint.addRule({
+ id: "overqualified-elements",
+ name: "Disallow overqualified elements",
+ desc: "Don't use IDs with elements (a#foo).",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ classes = {};
+
+ parser.addListener("startrule", function(event){
+ var selectors = event.selectors,
+ selector,
+ part,
+ modifier,
+ i, j, k;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+
+ for (j=0; j < selector.parts.length; j++){
+ part = selector.parts[j];
+ if (part.type == parser.SELECTOR_PART_TYPE){
+ for (k=0; k < part.modifiers.length; k++){
+ modifier = part.modifiers[k];
+ if (part.elementName && modifier.type == "id"){
+ reporter.report("Element (" + part + ") is overqualified, just use " + modifier + " without element name.", part.line, part.col, rule);
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "qualified-headings",
+ name: "Disallow qualified headings",
+ desc: "Headings should not be qualified (namespaced).",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ parser.addListener("startrule", function(event){
+ var selectors = event.selectors,
+ selector,
+ part,
+ i, j;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+
+ for (j=0; j < selector.parts.length; j++){
+ part = selector.parts[j];
+ if (part.type == parser.SELECTOR_PART_TYPE){
+ if (part.elementName && /h[1-6]/.test(part.elementName.toString()) && j > 0){
+ reporter.report("Heading (" + part.elementName + ") should not be qualified.", part.line, part.col, rule);
+ }
+ }
+ }
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "regex-selectors",
+ name: "Disallow selectors that look like regexs",
+ desc: "Selectors that look like regular expressions are slow and should be avoided.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ parser.addListener("startrule", function(event){
+ var selectors = event.selectors,
+ selector,
+ part,
+ modifier,
+ i, j, k;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+ for (j=0; j < selector.parts.length; j++){
+ part = selector.parts[j];
+ if (part.type == parser.SELECTOR_PART_TYPE){
+ for (k=0; k < part.modifiers.length; k++){
+ modifier = part.modifiers[k];
+ if (modifier.type == "attribute"){
+ if (/([\~\|\^\$\*]=)/.test(modifier)){
+ reporter.report("Attribute selectors with " + RegExp.$1 + " are slow!", modifier.line, modifier.col, rule);
+ }
+ }
+
+ }
+ }
+ }
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "rules-count",
+ name: "Rules Count",
+ desc: "Track how many rules there are.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ count = 0;
+ parser.addListener("startrule", function(){
+ count++;
+ });
+
+ parser.addListener("endstylesheet", function(){
+ reporter.stat("rule-count", count);
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "shorthand",
+ name: "Require shorthand properties",
+ desc: "Use shorthand properties where possible.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ prop, i, len,
+ propertiesToCheck = {},
+ properties,
+ mapping = {
+ "margin": [
+ "margin-top",
+ "margin-bottom",
+ "margin-left",
+ "margin-right"
+ ],
+ "padding": [
+ "padding-top",
+ "padding-bottom",
+ "padding-left",
+ "padding-right"
+ ]
+ };
+ for (prop in mapping){
+ if (mapping.hasOwnProperty(prop)){
+ for (i=0, len=mapping[prop].length; i < len; i++){
+ propertiesToCheck[mapping[prop][i]] = prop;
+ }
+ }
+ }
+
+ function startRule(event){
+ properties = {};
+ }
+ function endRule(event){
+
+ var prop, i, len, total;
+ for (prop in mapping){
+ if (mapping.hasOwnProperty(prop)){
+ total=0;
+
+ for (i=0, len=mapping[prop].length; i < len; i++){
+ total += properties[mapping[prop][i]] ? 1 : 0;
+ }
+
+ if (total == mapping[prop].length){
+ reporter.report("The properties " + mapping[prop].join(", ") + " can be replaced by " + prop + ".", event.line, event.col, rule);
+ }
+ }
+ }
+ }
+
+ parser.addListener("startrule", startRule);
+ parser.addListener("startfontface", startRule);
+ parser.addListener("property", function(event){
+ var name = event.property.toString().toLowerCase(),
+ value = event.value.parts[0].value;
+
+ if (propertiesToCheck[name]){
+ properties[name] = 1;
+ }
+ });
+
+ parser.addListener("endrule", endRule);
+ parser.addListener("endfontface", endRule);
+
+ }
+
+});
+CSSLint.addRule({
+ id: "star-property-hack",
+ name: "Disallow properties with a star prefix",
+ desc: "Checks for the star property hack (targets IE6/7)",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+ parser.addListener("property", function(event){
+ var property = event.property;
+
+ if (property.hack == "*") {
+ reporter.report("Property with star prefix found.", event.property.line, event.property.col, rule);
+ }
+ });
+ }
+});
+CSSLint.addRule({
+ id: "text-indent",
+ name: "Disallow negative text-indent",
+ desc: "Checks for text indent less than -99px",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ textIndent,
+ direction;
+
+
+ function startRule(event){
+ textIndent = false;
+ direction = "inherit";
+ }
+ function endRule(event){
+ if (textIndent && direction != "ltr"){
+ reporter.report("Negative text-indent doesn't work well with RTL. If you use text-indent for image replacement explicitly set direction for that item to ltr.", textIndent.line, textIndent.col, rule);
+ }
+ }
+
+ parser.addListener("startrule", startRule);
+ parser.addListener("startfontface", startRule);
+ parser.addListener("property", function(event){
+ var name = event.property.toString().toLowerCase(),
+ value = event.value;
+
+ if (name == "text-indent" && value.parts[0].value < -99){
+ textIndent = event.property;
+ } else if (name == "direction" && value == "ltr"){
+ direction = "ltr";
+ }
+ });
+
+ parser.addListener("endrule", endRule);
+ parser.addListener("endfontface", endRule);
+
+ }
+
+});
+CSSLint.addRule({
+ id: "underscore-property-hack",
+ name: "Disallow properties with an underscore prefix",
+ desc: "Checks for the underscore property hack (targets IE6)",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+ parser.addListener("property", function(event){
+ var property = event.property;
+
+ if (property.hack == "_") {
+ reporter.report("Property with underscore prefix found.", event.property.line, event.property.col, rule);
+ }
+ });
+ }
+});
+CSSLint.addRule({
+ id: "unique-headings",
+ name: "Headings should only be defined once",
+ desc: "Headings should be defined only once.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ var headings = {
+ h1: 0,
+ h2: 0,
+ h3: 0,
+ h4: 0,
+ h5: 0,
+ h6: 0
+ };
+
+ parser.addListener("startrule", function(event){
+ var selectors = event.selectors,
+ selector,
+ part,
+ pseudo,
+ i, j;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+ part = selector.parts[selector.parts.length-1];
+
+ if (part.elementName && /(h[1-6])/i.test(part.elementName.toString())){
+
+ for (j=0; j < part.modifiers.length; j++){
+ if (part.modifiers[j].type == "pseudo"){
+ pseudo = true;
+ break;
+ }
+ }
+
+ if (!pseudo){
+ headings[RegExp.$1]++;
+ if (headings[RegExp.$1] > 1) {
+ reporter.report("Heading (" + part.elementName + ") has already been defined.", part.line, part.col, rule);
+ }
+ }
+ }
+ }
+ });
+
+ parser.addListener("endstylesheet", function(event){
+ var prop,
+ messages = [];
+
+ for (prop in headings){
+ if (headings.hasOwnProperty(prop)){
+ if (headings[prop] > 1){
+ messages.push(headings[prop] + " " + prop + "s");
+ }
+ }
+ }
+
+ if (messages.length){
+ reporter.rollupWarn("You have " + messages.join(", ") + " defined in this stylesheet.", rule);
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "universal-selector",
+ name: "Disallow universal selector",
+ desc: "The universal selector (*) is known to be slow.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ parser.addListener("startrule", function(event){
+ var selectors = event.selectors,
+ selector,
+ part,
+ modifier,
+ i, j, k;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+
+ part = selector.parts[selector.parts.length-1];
+ if (part.elementName == "*"){
+ reporter.report(rule.desc, part.line, part.col, rule);
+ }
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "unqualified-attributes",
+ name: "Disallow unqualified attribute selectors",
+ desc: "Unqualified attribute selectors are known to be slow.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+
+ parser.addListener("startrule", function(event){
+
+ var selectors = event.selectors,
+ selector,
+ part,
+ modifier,
+ i, j, k;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+
+ part = selector.parts[selector.parts.length-1];
+ if (part.type == parser.SELECTOR_PART_TYPE){
+ for (k=0; k < part.modifiers.length; k++){
+ modifier = part.modifiers[k];
+ if (modifier.type == "attribute" && (!part.elementName || part.elementName == "*")){
+ reporter.report(rule.desc, part.line, part.col, rule);
+ }
+ }
+ }
+
+ }
+ });
+ }
+
+});
+CSSLint.addRule({
+ id: "vendor-prefix",
+ name: "Require standard property with vendor prefix",
+ desc: "When using a vendor-prefixed property, make sure to include the standard one.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ properties,
+ num,
+ propertiesToCheck = {
+ "-webkit-border-radius": "border-radius",
+ "-webkit-border-top-left-radius": "border-top-left-radius",
+ "-webkit-border-top-right-radius": "border-top-right-radius",
+ "-webkit-border-bottom-left-radius": "border-bottom-left-radius",
+ "-webkit-border-bottom-right-radius": "border-bottom-right-radius",
+
+ "-o-border-radius": "border-radius",
+ "-o-border-top-left-radius": "border-top-left-radius",
+ "-o-border-top-right-radius": "border-top-right-radius",
+ "-o-border-bottom-left-radius": "border-bottom-left-radius",
+ "-o-border-bottom-right-radius": "border-bottom-right-radius",
+
+ "-moz-border-radius": "border-radius",
+ "-moz-border-radius-topleft": "border-top-left-radius",
+ "-moz-border-radius-topright": "border-top-right-radius",
+ "-moz-border-radius-bottomleft": "border-bottom-left-radius",
+ "-moz-border-radius-bottomright": "border-bottom-right-radius",
+
+ "-moz-column-count": "column-count",
+ "-webkit-column-count": "column-count",
+
+ "-moz-column-gap": "column-gap",
+ "-webkit-column-gap": "column-gap",
+
+ "-moz-column-rule": "column-rule",
+ "-webkit-column-rule": "column-rule",
+
+ "-moz-column-rule-style": "column-rule-style",
+ "-webkit-column-rule-style": "column-rule-style",
+
+ "-moz-column-rule-color": "column-rule-color",
+ "-webkit-column-rule-color": "column-rule-color",
+
+ "-moz-column-rule-width": "column-rule-width",
+ "-webkit-column-rule-width": "column-rule-width",
+
+ "-moz-column-width": "column-width",
+ "-webkit-column-width": "column-width",
+
+ "-webkit-column-span": "column-span",
+ "-webkit-columns": "columns",
+
+ "-moz-box-shadow": "box-shadow",
+ "-webkit-box-shadow": "box-shadow",
+
+ "-moz-transform" : "transform",
+ "-webkit-transform" : "transform",
+ "-o-transform" : "transform",
+ "-ms-transform" : "transform",
+
+ "-moz-transform-origin" : "transform-origin",
+ "-webkit-transform-origin" : "transform-origin",
+ "-o-transform-origin" : "transform-origin",
+ "-ms-transform-origin" : "transform-origin",
+
+ "-moz-box-sizing" : "box-sizing",
+ "-webkit-box-sizing" : "box-sizing",
+
+ "-moz-user-select" : "user-select",
+ "-khtml-user-select" : "user-select",
+ "-webkit-user-select" : "user-select"
+ };
+ function startRule(){
+ properties = {};
+ num=1;
+ }
+ function endRule(event){
+ var prop,
+ i, len,
+ standard,
+ needed,
+ actual,
+ needsStandard = [];
+
+ for (prop in properties){
+ if (propertiesToCheck[prop]){
+ needsStandard.push({ actual: prop, needed: propertiesToCheck[prop]});
+ }
+ }
+
+ for (i=0, len=needsStandard.length; i < len; i++){
+ needed = needsStandard[i].needed;
+ actual = needsStandard[i].actual;
+
+ if (!properties[needed]){
+ reporter.report("Missing standard property '" + needed + "' to go along with '" + actual + "'.", properties[actual][0].name.line, properties[actual][0].name.col, rule);
+ } else {
+ if (properties[needed][0].pos < properties[actual][0].pos){
+ reporter.report("Standard property '" + needed + "' should come after vendor-prefixed property '" + actual + "'.", properties[actual][0].name.line, properties[actual][0].name.col, rule);
+ }
+ }
+ }
+
+ }
+
+ parser.addListener("startrule", startRule);
+ parser.addListener("startfontface", startRule);
+ parser.addListener("startpage", startRule);
+ parser.addListener("startpagemargin", startRule);
+ parser.addListener("startkeyframerule", startRule);
+
+ parser.addListener("property", function(event){
+ var name = event.property.text.toLowerCase();
+
+ if (!properties[name]){
+ properties[name] = [];
+ }
+
+ properties[name].push({ name: event.property, value : event.value, pos:num++ });
+ });
+
+ parser.addListener("endrule", endRule);
+ parser.addListener("endfontface", endRule);
+ parser.addListener("endpage", endRule);
+ parser.addListener("endpagemargin", endRule);
+ parser.addListener("endkeyframerule", endRule);
+ }
+
+});
+CSSLint.addRule({
+ id: "zero-units",
+ name: "Disallow units for 0 values",
+ desc: "You don't need to specify units when a value is 0.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this;
+ parser.addListener("property", function(event){
+ var parts = event.value.parts,
+ i = 0,
+ len = parts.length;
+
+ while(i < len){
+ if ((parts[i].units || parts[i].type == "percentage") && parts[i].value === 0 && parts[i].type != "time"){
+ reporter.report("Values of 0 shouldn't have units specified.", parts[i].line, parts[i].col, rule);
+ }
+ i++;
+ }
+
+ });
+
+ }
+
+});
+
+CSSLint.addRule({
+ id: "custom-background-class",
+ name: "Remember .custom-background",
+ desc: "Remind users to use the .custom-background class on the body selector.",
+ browsers: "All",
+ init: function(parser, reporter){
+ var rule = this,
+ pending = false,
+ report_warning = false;
+
+ parser.addListener("property", function(event){
+ if (pending && event.property.toString().toLowerCase().indexOf('background') === 0)
+ report_warning = true;
+ });
+
+ parser.addListener("startrule", function (event) {
+ var selectors = event.selectors,
+ selector,
+ part,
+ i, j;
+
+ for (i=0; i < selectors.length; i++){
+ selector = selectors[i];
+
+ for (j=0; j < selector.parts.length; j++){
+ part = selector.parts[j];
+
+ if (part.type == parser.SELECTOR_PART_TYPE){
+ if (part.elementName && part.elementName.toString() == 'body' && part.modifiers.length == 0) {
+ pending = true;
+ }
+ }
+ }
+ }
+ });
+
+ parser.addListener("endrule", function (event) {
+ if (report_warning)
+ reporter.report("If you want to override any custom background styles, be sure to add '.custom-background' to your 'body' selector.", event.line, event.col, rule);
+
+ report_warning = false;
+ pending = false;
+ });
+ }
+});
+
+exports.CSSLint = CSSLint;
+
+
+});
diff --git a/plugins/jetpack/modules/custom-css/custom-css/js/safecss-ace.js b/plugins/jetpack/modules/custom-css/custom-css/js/safecss-ace.js
index 65b01d6e..2fb46191 100644
--- a/plugins/jetpack/modules/custom-css/custom-css/js/safecss-ace.js
+++ b/plugins/jetpack/modules/custom-css/custom-css/js/safecss-ace.js
@@ -1,9 +1,11 @@
(function(global, $){
// shared scope insied IIFE in case it's needed.
var editor;
- var syncCSS = function() {
- $("#safecss").val( editor.getSession().getValue() );
+
+ var syncCSS = function () {
+ $( "#safecss" ).val( editor.getSession().getValue() );
};
+
var loadAce = function() {
// Set up ACE editor
ace.config.set( 'modePath', safecssAceSrcPath );
@@ -19,27 +21,30 @@
editor.setShowPrintMargin( false );
// Grab straight from the textarea
editor.getSession().setValue( $("#safecss").val() );
- // We're editing CSS content
- var CSSMode = ace.require( 'ace/mode/css' ).Mode;
- editor.getSession().setMode( new CSSMode() );
- // ace.js comes with the textmate coloring scheme already.
// kill the spinner
jQuery.fn.spin && $("#safecss-container").spin( false );
- /*
- // TODO: Add shortcuts for save and preview
- editor.commands.addCommand({
- name: 'cssPreview',
- bindKey: {
- win: 'Ctrl-P',
- mac: 'Command-P',
- sender: 'editor'
- },
- exec: function( env, args, request ) {
- safecss_update_content();
- jQuery( '#preview' ).click(); // this doesn't work :(
+
+ var preprocessorField = $( '#custom_css_preprocessor' );
+ function setCSSMode( preprocessor ) {
+ switch ( preprocessor ) {
+ case 'less':
+ var mode = ace.require( 'ace/mode/less' ).Mode;
+ break;
+ case 'sass':
+ var mode = ace.require( 'ace/mode/scss' ).Mode;
+ break;
+ default:
+ var mode = ace.require( 'ace/mode/css' ).Mode;
+ break;
}
+
+ editor.getSession().setMode( new mode() );
+ }
+
+ setCSSMode( preprocessorField.val() );
+ preprocessorField.on( 'change', function () {
+ setCSSMode( $( this ).val() );
} );
- */
// When submitting, make sure to include the updated CSS
// The Ace editor unfortunately doesn't handle this for us
@@ -54,16 +59,12 @@
}
// syntaxy goodness.
else {
- $( '#safecss-ace, #safecss-container' ).css( 'height',
+ $( '#safecss-ace, #safecss-container' ).css( 'height',
Math.max( 250, $( window ).height() - $( '#safecss-container' ).offset().top - $( '#wpadminbar' ).height() )
);
$(global).load(loadAce);
}
- // for now, expose the syncCSS function.
- global.aceSyncCSS = syncCSS;
-
-})(this, jQuery);
-
-
+ $( '#preview' ).on( 'click', syncCSS );
+})(this, jQuery); \ No newline at end of file
diff --git a/plugins/jetpack/modules/custom-css/custom-css/preprocessors.php b/plugins/jetpack/modules/custom-css/custom-css/preprocessors.php
index eef6ab43..e107b533 100644
--- a/plugins/jetpack/modules/custom-css/custom-css/preprocessors.php
+++ b/plugins/jetpack/modules/custom-css/custom-css/preprocessors.php
@@ -33,7 +33,7 @@ function jetpack_register_css_preprocessors( $preprocessors ) {
add_filter( 'jetpack_custom_css_preprocessors', 'jetpack_register_css_preprocessors' );
function jetpack_less_css_preprocess( $less ) {
- require( dirname( __FILE__ ) . '/preprocessors/lessc.inc.php' );
+ require_once( dirname( __FILE__ ) . '/preprocessors/lessc.inc.php' );
$compiler = new lessc();
diff --git a/plugins/jetpack/modules/enhanced-distribution.php b/plugins/jetpack/modules/enhanced-distribution.php
index b2a80155..daad2eb2 100644
--- a/plugins/jetpack/modules/enhanced-distribution.php
+++ b/plugins/jetpack/modules/enhanced-distribution.php
@@ -4,6 +4,7 @@
* Module Description: Share your public posts and comments to search engines and other services in real-time.
* Sort Order: 100
* First Introduced: 1.2
+ * Requires Connection: Yes
*/
Jetpack_Sync::sync_posts( __FILE__ );
diff --git a/plugins/jetpack/modules/featured-content/featured-content.php b/plugins/jetpack/modules/featured-content/featured-content.php
index 9cd511ed..ac394903 100644
--- a/plugins/jetpack/modules/featured-content/featured-content.php
+++ b/plugins/jetpack/modules/featured-content/featured-content.php
@@ -41,7 +41,7 @@ class Featured_Content {
* All custom functionality will be hooked into the "init" action.
*/
public static function setup() {
- add_action( 'init', array( __class__, 'init' ) );
+ add_action( 'init', array( __class__, 'init' ), 30 );
}
/**
@@ -413,12 +413,14 @@ class Featured_Content {
if ( isset( $input['tag-id'] ) )
$output['tag-id'] = absint( $input['tag-id'] );
- if ( isset( $input['tag-name'] ) ) {
+ if ( isset( $input['tag-name'] ) && ! empty( $input['tag-name'] ) ) {
$new_tag = wp_create_tag( $input['tag-name'] );
if ( ! is_wp_error( $new_tag ) && isset( $new_tag['term_id'] ) )
$tag = get_term( $new_tag['term_id'], 'post_tag' );
if ( isset( $tag->term_id ) )
$output['tag-id'] = $tag->term_id;
+ } else {
+ unset( $output['tag-id'] );
}
if ( isset( $input['quantity'] ) )
diff --git a/plugins/jetpack/modules/gravatar-hovercards.php b/plugins/jetpack/modules/gravatar-hovercards.php
index 9edd15a5..980317cd 100644
--- a/plugins/jetpack/modules/gravatar-hovercards.php
+++ b/plugins/jetpack/modules/gravatar-hovercards.php
@@ -4,6 +4,7 @@
* Module Description: Show a pop-up business card of your users' gravatar profiles in comments.
* Sort Order: 8
* First Introduced: 1.1
+ * Requires Connection: No
*/
define( 'GROFILES__CACHE_BUSTER', gmdate( 'YM' ) . 'aa' ); // Break CDN cache, increment when gravatar.com/js/gprofiles.js changes
@@ -13,11 +14,11 @@ function grofiles_hovercards_init() {
add_action( 'wp_enqueue_scripts', 'grofiles_attach_cards' );
add_action( 'wp_footer', 'grofiles_extra_data' );
add_action( 'admin_init', 'grofiles_add_settings' );
-
+
add_action( 'load-index.php', 'grofiles_admin_cards' );
add_action( 'load-users.php', 'grofiles_admin_cards' );
- add_action( 'load-edit-comments.php', 'grofiles_admin_cards' );
- add_action( 'load-options-discussion.php', 'grofiles_admin_cards_forced' );
+ add_action( 'load-edit-comments.php', 'grofiles_admin_cards' );
+ add_action( 'load-options-discussion.php', 'grofiles_admin_cards_forced' );
Jetpack::enable_module_configurable( __FILE__ );
Jetpack::module_configuration_load( __FILE__, 'gravatar_hovercards_configuration_load' );
@@ -52,7 +53,7 @@ function grofiles_setting_callback() {
global $current_user;
$checked = 'disabled' == get_option( 'gravatar_disable_hovercards' ) ? '' : 'checked="checked" ';
-
+
echo "<label id='gravatar-hovercard-options'><input {$checked}name='gravatar_disable_hovercards' id='gravatar_disable_hovercards' type='checkbox' value='enabled' class='code' /> " . __( "View people's profiles when you mouse over their Gravatars", 'jetpack' ) . "</label>";
?>
<style type="text/css">
@@ -167,7 +168,7 @@ function grofiles_get_avatar( $avatar, $author ) {
*/
function grofiles_attach_cards() {
global $blog_id;
-
+
if ( 'disabled' == get_option( 'gravatar_disable_hovercards' ) )
return;
diff --git a/plugins/jetpack/modules/holiday-snow.php b/plugins/jetpack/modules/holiday-snow.php
index 93e3f9cf..51bf3ed6 100644
--- a/plugins/jetpack/modules/holiday-snow.php
+++ b/plugins/jetpack/modules/holiday-snow.php
@@ -5,6 +5,7 @@
* Adds falling snow to a blog starting December 1 and ending January 3.
* Not a module that is activated/deactivated
* First Introduced: 2.0.3 ??
+ * Requires Connection: No
*/
class Jetpack_Holiday_Snow_Settings {
diff --git a/plugins/jetpack/modules/infinite-scroll.php b/plugins/jetpack/modules/infinite-scroll.php
index 857ac6e0..2a94bf42 100644
--- a/plugins/jetpack/modules/infinite-scroll.php
+++ b/plugins/jetpack/modules/infinite-scroll.php
@@ -4,6 +4,7 @@
* Module Description: Automatically pull the next set of posts into view when the reader approaches the bottom of the page.
* Sort Order: 14
* First Introduced: 2.0
+ * Requires Connection: No
*/
/**
diff --git a/plugins/jetpack/modules/infinite-scroll/infinity.css b/plugins/jetpack/modules/infinite-scroll/infinity.css
index dd39179e..0a09f245 100644
--- a/plugins/jetpack/modules/infinite-scroll/infinity.css
+++ b/plugins/jetpack/modules/infinite-scroll/infinity.css
@@ -2,15 +2,11 @@
-------------------------------------------------------------- */
.infinite-wrap {
-/* border-top: 2px solid #444;
- border-top: 2px solid rgba(68,68,68,0.8);
- padding: 20px 0 0; */
}
.infinite-loader {
color: #000;
display: block;
height: 28px;
- margin: 10px;
text-indent: -9999px;
}
#infinite-handle span {
@@ -58,6 +54,7 @@
border-color: rgba( 0, 0, 0, 0.1 );
border-style: solid;
border-width: 1px 0 0;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
margin: 0 auto;
overflow: hidden;
diff --git a/plugins/jetpack/modules/infinite-scroll/infinity.js b/plugins/jetpack/modules/infinite-scroll/infinity.js
index 7a76d8f2..51099153 100644
--- a/plugins/jetpack/modules/infinite-scroll/infinity.js
+++ b/plugins/jetpack/modules/infinite-scroll/infinity.js
@@ -79,14 +79,13 @@ Scroller = function( settings ) {
/**
* Check whether we should fetch any additional posts.
- *
- * By default, checks whether the bottom of the viewport is within one
- * viewport-height of the bottom of the content.
*/
Scroller.prototype.check = function() {
var bottom = this.window.scrollTop() + this.window.height(),
threshold = this.element.offset().top + this.element.outerHeight(false) - this.window.height();
+ threshold = Math.round( threshold * 0.75 );
+
return bottom > threshold;
};
@@ -457,7 +456,7 @@ Scroller.prototype.updateURL = function( page ) {
*/
$( document ).ready( function() {
// Check for our variables
- if ( ! infiniteScroll )
+ if ( 'object' != typeof infiniteScroll )
return;
// Set ajaxurl (for brevity)
@@ -487,4 +486,4 @@ $( document ).ready( function() {
});
-})(jQuery); // Close closure \ No newline at end of file
+})(jQuery); // Close closure
diff --git a/plugins/jetpack/modules/infinite-scroll/infinity.php b/plugins/jetpack/modules/infinite-scroll/infinity.php
index ad57f1b6..20ff5eff 100644
--- a/plugins/jetpack/modules/infinite-scroll/infinity.php
+++ b/plugins/jetpack/modules/infinite-scroll/infinity.php
@@ -17,17 +17,20 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/
class The_Neverending_Home_Page {
/**
+ * Register actions and filters, plus parse IS settings
*
+ * @uses add_action, add_filter, self::get_settings
+ * @return null
*/
function __construct() {
- add_filter( 'pre_get_posts', array( $this, 'posts_per_page_query' ) );
+ add_action( 'pre_get_posts', array( $this, 'posts_per_page_query' ) );
add_action( 'admin_init', array( $this, 'settings_api_init' ) );
add_action( 'template_redirect', array( $this, 'action_template_redirect' ) );
add_action( 'template_redirect', array( $this, 'ajax_response' ) );
add_action( 'custom_ajax_infinite_scroll', array( $this, 'query' ) );
add_action( 'the_post', array( $this, 'preserve_more_tag' ) );
- add_action( 'get_footer', array( $this, 'footer' ) );
+ add_action( 'wp_footer', array( $this, 'footer' ) );
// Plugin compatibility
add_filter( 'grunion_contact_form_redirect_url', array( $this, 'filter_grunion_redirect_url' ) );
@@ -55,14 +58,15 @@ class The_Neverending_Home_Page {
$css_pattern = '#[^A-Z\d\-_]#i';
$settings = $defaults = array(
- 'type' => 'scroll', // scroll | click
- 'requested_type' => 'scroll', // store the original type for use when logic overrides it
- 'footer_widgets' => false, // true | false | sidebar_id | array of sidebar_ids -- last two are checked with is_active_sidebar
- 'container' => 'content', // container html id
- 'wrapper' => true, // true | false | html class
- 'render' => false, // optional function, otherwise the `content` template part will be used
- 'footer' => true, // boolean to enable or disable the infinite footer | string to provide an html id to derive footer width from
- 'posts_per_page' => false // int | false to set based on IS type
+ 'type' => 'scroll', // scroll | click
+ 'requested_type' => 'scroll', // store the original type for use when logic overrides it
+ 'footer_widgets' => false, // true | false | sidebar_id | array of sidebar_ids -- last two are checked with is_active_sidebar
+ 'container' => 'content', // container html id
+ 'wrapper' => true, // true | false | html class
+ 'render' => false, // optional function, otherwise the `content` template part will be used
+ 'footer' => true, // boolean to enable or disable the infinite footer | string to provide an html id to derive footer width from
+ 'footer_callback' => false, // function to be called to render the IS footer, in place of the default
+ 'posts_per_page' => false // int | false to set based on IS type
);
// Validate settings passed through add_theme_support()
@@ -93,8 +97,7 @@ class The_Neverending_Home_Page {
case 'wrapper' :
if ( 'wrapper' == $key && is_bool( $value ) ) {
$settings[ $key ] = $value;
- }
- else {
+ } else {
$value = preg_replace( $css_pattern, '', $value );
if ( ! empty( $value ) )
@@ -115,8 +118,7 @@ class The_Neverending_Home_Page {
case 'footer' :
if ( is_bool( $value ) ) {
$settings[ $key ] = $value;
- }
- elseif ( is_string( $value ) ) {
+ } elseif ( is_string( $value ) ) {
$value = preg_replace( $css_pattern, '', $value );
if ( ! empty( $value ) )
@@ -125,6 +127,14 @@ class The_Neverending_Home_Page {
break;
+ case 'footer_callback' :
+ if ( is_callable( $value ) )
+ $settings[ $key ] = $value;
+ else
+ $settings[ $key ] = false;
+
+ break;
+
case 'posts_per_page' :
if ( is_numeric( $value ) )
$settings[ $key ] = (int) $value;
@@ -137,9 +147,9 @@ class The_Neverending_Home_Page {
break;
}
}
- }
- // Checks below are for backwards compatibility
- elseif ( is_string( $_settings[0] ) ) {
+ } elseif ( is_string( $_settings[0] ) ) {
+ // Checks below are for backwards compatibility
+
// Container to append new posts to
$settings['container'] = preg_replace( $css_pattern, '', $_settings[0] );
@@ -157,8 +167,7 @@ class The_Neverending_Home_Page {
// It is safe to use `is_active_sidebar()` before the sidebar is registered as this function doesn't check for a sidebar's existence when determining if it contains any widgets.
if ( function_exists( 'infinite_scroll_has_footer_widgets' ) ) {
$settings['footer_widgets'] = (bool) infinite_scroll_has_footer_widgets();
- }
- elseif ( is_array( $settings['footer_widgets'] ) ) {
+ } elseif ( is_array( $settings['footer_widgets'] ) ) {
$sidebar_ids = $settings['footer_widgets'];
$settings['footer_widgets'] = false;
@@ -171,8 +180,7 @@ class The_Neverending_Home_Page {
unset( $sidebar_ids );
unset( $sidebar_id );
- }
- elseif ( is_string( $settings['footer_widgets'] ) ) {
+ } elseif ( is_string( $settings['footer_widgets'] ) ) {
$settings['footer_widgets'] = (bool) is_active_sidebar( $settings['footer_widgets'] );
}
@@ -205,6 +213,18 @@ class The_Neverending_Home_Page {
}
/**
+ * Retrieve the query used with Infinite Scroll
+ *
+ * @global $wp_the_query
+ * @uses apply_filters
+ * @return object
+ */
+ static function wp_query() {
+ global $wp_the_query;
+ return apply_filters( 'infinite_scroll_query_object', $wp_the_query );
+ }
+
+ /**
* Has infinite scroll been triggered?
*/
static function got_infinity() {
@@ -284,7 +304,7 @@ class The_Neverending_Home_Page {
add_filter( 'body_class', array( $this, 'body_class' ) );
// Add our scripts.
- wp_enqueue_script( 'the-neverending-homepage', plugins_url( 'infinity.js', __FILE__ ), array( 'jquery' ), '20130101' );
+ wp_enqueue_script( 'the-neverending-homepage', plugins_url( 'infinity.js', __FILE__ ), array( 'jquery' ), '20130523' );
// Add our default styles.
wp_enqueue_style( 'the-neverending-homepage', plugins_url( 'infinity.css', __FILE__ ), array(), '20120612' );
@@ -322,7 +342,7 @@ class The_Neverending_Home_Page {
* @return string 'Y-m-d H:i:s' or null
*/
function set_last_post_time( $date = false ) {
- global $posts;
+ $posts = self::wp_query()->posts;
$count = count( $posts );
if ( ! empty( $date ) && preg_match( '|\d{4}\-\d{2}\-\d{2}|', $_GET['date'] ) ) {
@@ -339,8 +359,7 @@ class The_Neverending_Home_Page {
// If the function is called again but we already have a value, return it
if ( null != self::$the_time ) {
return self::$the_time;
- }
- else if ( isset( $last_post->post_date_gmt ) ) {
+ } elseif ( isset( $last_post->post_date_gmt ) ) {
// Grab the latest post time in Y-m-d H:i:s gmt format
self::$the_time = $last_post->post_date_gmt;
}
@@ -353,8 +372,11 @@ class The_Neverending_Home_Page {
* will always return results prior to (descending sort)
* or before (ascending sort) the last post date.
*
+ * @global $wpdb
* @param string $where
* @param object $query
+ * @uses apply_filters
+ * @uses self::set_last_post_time
* @filter posts_where
* @return string
*/
@@ -364,7 +386,9 @@ class The_Neverending_Home_Page {
$operator = 'ASC' == $query->get( 'order' ) ? '>' : '<';
// Construct the date query using our timestamp
- $where .= $wpdb->prepare( " AND post_date_gmt {$operator} %s", self::set_last_post_time() );
+ $clause = $wpdb->prepare( " AND {$wpdb->posts}.post_date_gmt {$operator} %s", self::set_last_post_time() );
+
+ $where .= apply_filters( 'infinite_scroll_posts_where', $clause, $query, $operator, self::set_last_post_time() );
return $where;
}
@@ -372,15 +396,12 @@ class The_Neverending_Home_Page {
/**
* Let's overwrite the default post_per_page setting to always display a fixed amount.
*
- * @global $wp_the_query Used to provide compatibility back to WP 3.2
* @param object $query
- * @uses self::archive_supports_infinity, self::get_settings
+ * @uses is_admin, self::archive_supports_infinity, self::get_settings
* @return null
*/
function posts_per_page_query( $query ) {
- global $wp_the_query;
-
- if ( self::archive_supports_infinity() && $query === $wp_the_query ) // After 3.3, this line would be: if ( self::archive_supports_infinity() && $query->is_main_query() )
+ if ( ! is_admin() && self::archive_supports_infinity() && $query->is_main_query() )
$query->set( 'posts_per_page', self::get_settings()->posts_per_page );
}
@@ -438,12 +459,13 @@ class The_Neverending_Home_Page {
/**
* Prints the relevant infinite scroll settings in JS.
*
+ * @global $wp_rewrite
* @uses self::get_settings, esc_js, esc_url_raw, self::has_wrapper, __, apply_filters, do_action
* @action wp_head
* @return string
*/
function action_wp_head() {
- global $wp_query, $wp_the_query, $wp_rewrite;
+ global $wp_rewrite;
// Base JS settings
$js_settings = array(
@@ -459,7 +481,7 @@ class The_Neverending_Home_Page {
'scripts' => array(),
'styles' => array(),
'google_analytics' => false,
- 'offset' => $wp_query->get( 'paged' ),
+ 'offset' => self::wp_query()->get( 'paged' ),
'history' => array(
'host' => preg_replace( '#^http(s)?://#i', '', untrailingslashit( get_option( 'home' ) ) ),
'path' => self::get_request_path(),
@@ -518,8 +540,7 @@ class The_Neverending_Home_Page {
$path = '/' . $path;
$path = user_trailingslashit( $path );
- }
- else {
+ } else {
// Clean up raw $_GET input
$path = array_map( 'sanitize_text_field', $_GET );
$path = array_filter( $path );
@@ -606,7 +627,7 @@ class The_Neverending_Home_Page {
else
$ver = $wp_scripts->registered[ $handle ]->ver ? $wp_scripts->registered[ $handle ]->ver : $wp_scripts->default_version;
- if ( isset($wp_scripts->args[ $handle ] ) )
+ if ( isset( $wp_scripts->args[ $handle ] ) )
$ver = $ver ? $ver . '&amp;' . $wp_scripts->args[$handle] : $wp_scripts->args[$handle];
// Full script source with version info
@@ -721,17 +742,19 @@ class The_Neverending_Home_Page {
*
* @global $wp_query
* @global $wp_the_query
- * @uses current_user_can, get_option, self::set_last_post_time, current_user_can, apply_filters, self::get_settings, add_filter, WP_Query, remove_filter, have_posts, wp_head, do_action, add_action, this::render, this::has_wrapper, esc_attr, wp_footer, sharing_register_post_for_share_counts, get_the_id
+ * @uses current_theme_supports, get_option, self::wp_query, self::set_last_post_time, current_user_can, apply_filters, self::get_settings, add_filter, WP_Query, remove_filter, have_posts, wp_head, do_action, add_action, this::render, this::has_wrapper, esc_attr, wp_footer, sharing_register_post_for_share_counts, get_the_id
* @return string or null
*/
function query() {
- global $wp_query, $wp_the_query;
-
if ( ! isset( $_GET['page'] ) || ! current_theme_supports( 'infinite-scroll' ) )
die;
$page = (int) $_GET['page'];
+
$sticky = get_option( 'sticky_posts' );
+ $post__not_in = self::wp_query()->get( 'post__not_in' );
+ if ( ! empty( $post__not_in ) )
+ $sticky = array_unique( array_merge( $sticky, $post__not_in ) );
if ( ! empty( $_GET['date'] ) )
self::set_last_post_time( $_GET['date'] );
@@ -742,7 +765,7 @@ class The_Neverending_Home_Page {
$order = in_array( $_GET['order'], array( 'ASC', 'DESC' ) ) ? $_GET['order'] : 'DESC';
- $query_args = array_merge( $wp_the_query->query_vars, array(
+ $query_args = array_merge( self::wp_query()->query_vars, array(
'paged' => $page,
'post_status' => $post_status,
'posts_per_page' => self::get_settings()->posts_per_page,
@@ -751,7 +774,7 @@ class The_Neverending_Home_Page {
) );
// By default, don't query for a specific page of a paged post object.
- // This argument comes from merging $wp_the_query.
+ // This argument can come from merging self::wp_query() into $query_args above.
// Since IS is only used on archives, we should always display the first page of any paged content.
unset( $query_args['page'] );
@@ -760,7 +783,7 @@ class The_Neverending_Home_Page {
// Add query filter that checks for posts below the date
add_filter( 'posts_where', array( $this, 'query_time_filter' ), 10, 2 );
- $wp_the_query = $wp_query = new WP_Query( $query_args );
+ $GLOBALS['wp_the_query'] = $GLOBALS['wp_query'] = new WP_Query( $query_args );
remove_filter( 'posts_where', array( $this, 'query_time_filter' ), 10, 2 );
@@ -794,8 +817,7 @@ class The_Neverending_Home_Page {
unset( $results['html'] );
do_action( 'infinite_scroll_empty' );
$results['type'] = 'empty';
- }
- elseif ( $this->has_wrapper() ) {
+ } elseif ( $this->has_wrapper() ) {
$wrapper_classes = is_string( self::get_settings()->wrapper ) ? self::get_settings()->wrapper : 'infinite-wrap';
$wrapper_classes .= ' infinite-view-' . $page;
$wrapper_classes = trim( $wrapper_classes );
@@ -825,7 +847,7 @@ class The_Neverending_Home_Page {
$results['type'] = 'empty';
}
- echo json_encode( apply_filters( 'infinite_scroll_results', $results, $query_args, $wp_query ) );
+ echo json_encode( apply_filters( 'infinite_scroll_results', $results, $query_args, self::wp_query() ) );
die;
}
@@ -847,17 +869,19 @@ class The_Neverending_Home_Page {
/**
* Allow plugins to filter what archives Infinite Scroll supports
*
- * @uses apply_filters, current_theme_supports, is_home, is_archive, self::get_settings
+ * @uses current_theme_supports, is_home, is_archive, apply_filters, self::get_settings
* @return bool
*/
public static function archive_supports_infinity() {
- return (bool) apply_filters( 'infinite_scroll_archive_supported', current_theme_supports( 'infinite-scroll' ) && ( is_home() || is_archive() ), self::get_settings() );
+ $supported = current_theme_supports( 'infinite-scroll' ) && ( is_home() || is_archive() );
+
+ return (bool) apply_filters( 'infinite_scroll_archive_supported', $supported, self::get_settings() );
}
/**
* The Infinite Blog Footer
*
- * @uses self::get_settings, self::set_last_post_time, self::archive_supports_infinity, __, wp_get_theme, get_current_theme, apply_filters, home_url, esc_attr, get_bloginfo, bloginfo
+ * @uses self::get_settings, self::set_last_post_time, self::archive_supports_infinity, self::default_footer
* @return string or null
*/
function footer() {
@@ -873,6 +897,20 @@ class The_Neverending_Home_Page {
if ( 'scroll' != self::get_settings()->type || ! self::archive_supports_infinity() )
return;
+ // Display a footer, either user-specified or a default
+ if ( false !== self::get_settings()->footer_callback && is_callable( self::get_settings()->footer_callback ) )
+ call_user_func( self::get_settings()->footer_callback, self::get_settings() );
+ else
+ self::default_footer();
+ }
+
+ /**
+ * Render default IS footer
+ *
+ * @uses __, wp_get_theme, get_current_theme, apply_filters, home_url, esc_attr, get_bloginfo, bloginfo
+ * @return string
+ */
+ private function default_footer() {
$credits = '<a href="http://wordpress.org/" rel="generator">Proudly powered by WordPress</a> ';
$credits .= sprintf( __( 'Theme: %1$s.', 'jetpack' ), function_exists( 'wp_get_theme' ) ? wp_get_theme()->Name : get_current_theme() );
$credits = apply_filters( 'infinite_scroll_credit', $credits );
diff --git a/plugins/jetpack/modules/json-api.php b/plugins/jetpack/modules/json-api.php
index fb1473ff..e0722317 100644
--- a/plugins/jetpack/modules/json-api.php
+++ b/plugins/jetpack/modules/json-api.php
@@ -4,6 +4,7 @@
* Module Description: Allow applications to securely access your content through the cloud.
* Sort Order: 100
* First Introduced: 1.9
+ * Requires Connection: Yes
*/
function jetpack_json_api_toggle() {
diff --git a/plugins/jetpack/modules/latex.php b/plugins/jetpack/modules/latex.php
index 76066cd6..eb58f797 100644
--- a/plugins/jetpack/modules/latex.php
+++ b/plugins/jetpack/modules/latex.php
@@ -4,6 +4,7 @@
* Module Description: Mark up your posts with the <img src="//s0.wp.com/latex.php?latex=%5CLaTeX&amp;bg=transparent&amp;fg=000&amp;s=-2" alt="LaTeX logo" title="LaTeX" style="vertical-align: -25%" /> markup language, perfect for complex mathematical equations and other &#252;ber-geekery.
* Sort Order: 12
* First Introduced: 1.1
+ * Requires Connection: Yes
*/
/**
diff --git a/plugins/jetpack/modules/likes.php b/plugins/jetpack/modules/likes.php
index 753d4ab4..ab8b7b7a 100644
--- a/plugins/jetpack/modules/likes.php
+++ b/plugins/jetpack/modules/likes.php
@@ -4,11 +4,12 @@
* Module Description: Likes are a way for people to show their appreciation for content you have written. It’s also a way for you to show the world how popular your content has become.
* First Introduced: 2.2
* Sort Order: 4
+ * Requires Connection: Yes
*/
class Jetpack_Likes {
- var $version = '20130226';
+ var $version = '20130620a';
- function &init() {
+ public static function init() {
static $instance = NULL;
if ( ! $instance ) {
@@ -22,13 +23,14 @@ class Jetpack_Likes {
$this->in_jetpack = ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? false : true;
add_action( 'init', array( &$this, 'action_init' ) );
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
if ( $this->in_jetpack ) {
add_action( 'jetpack_activate_module_likes', array( $this, 'module_toggle' ) );
add_action( 'jetpack_deactivate_module_likes', array( $this, 'module_toggle' ) );
Jetpack::enable_module_configurable( __FILE__ );
- Jetpack::module_configuration_load( __FILE__, array( 'Jetpack_Likes', 'configuration_redirect' ) );
+ Jetpack::module_configuration_load( __FILE__, array( $this, 'configuration_redirect' ) );
add_action('admin_print_scripts-settings_page_sharing', array( &$this, 'load_jp_css' ) );
add_filter( 'sharing_show_buttons_on_row_start', array( $this, 'configuration_target_area' ) );
@@ -53,12 +55,17 @@ class Jetpack_Likes {
add_filter( 'sharing_meta_box_title', array( $this, 'add_likes_to_sharing_meta_box_title' ) );
add_action( 'start_sharing_meta_box_content', array( $this, 'meta_box_content' ) );
}
+
+ Jetpack_Sync::sync_options( __FILE__, 'social_notifications_like' );
+
} else { // wpcom
add_action( 'admin_init', array( $this, 'add_meta_box' ) );
add_action( 'end_likes_meta_box_content', array( $this, 'sharing_meta_box_content' ) );
add_filter( 'likes_meta_box_title', array( $this, 'add_likes_to_sharing_meta_box_title' ) );
}
+ add_action( 'admin_init', array( $this, 'admin_discussion_likes_settings_init' ) ); // Likes notifications
+
add_action( 'admin_bar_menu', array( $this, 'admin_bar_likes' ), 60 );
add_action( 'save_post', array( $this, 'meta_box_save' ) );
@@ -195,6 +202,65 @@ class Jetpack_Likes {
}
/**
+ * Options to be added to the discussion page (see also admin_settings_init, etc below for Sharing settings page)
+ */
+
+ function admin_discussion_likes_settings_init() {
+ // Add a temporary section, until we can move the setting out of there and with the rest of the email notification settings
+ add_settings_section( 'likes-notifications', __( 'Likes Notifications', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_section' ), 'discussion' );
+ add_settings_field( 'social-notifications', __( 'Email me whenever', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_field' ), 'discussion', 'likes-notifications' );
+ // Register the setting
+ register_setting( 'discussion', 'social_notifications_like', array( $this, 'admin_discussion_likes_settings_validate' ) );
+ }
+
+ function admin_discussion_likes_settings_section() {
+ // Atypical usage here. We emit jquery to move likes notification checkbox to be with the rest of the email notification settings
+?>
+ <script type="text/javascript">
+ jQuery( function( $ ) {
+ var table = $( '#social_notifications_like' ).parents( 'table:first' ),
+ header = table.prevAll( 'h3:first' ),
+ newParent = $( '#moderation_notify' ).parent( 'label' ).parent();
+
+ if ( !table.size() || !header.size() || !newParent.size() ) {
+ return;
+ }
+
+ newParent.append( '<br/>' ).append( table.end().parent( 'label' ).siblings().andSelf() );
+ header.remove();
+ table.remove();
+ } );
+ </script>
+<?php
+ }
+
+ function admin_likes_get_option( $option ) {
+ if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $option_setting = get_blog_option( get_current_blog_id(), $option );
+ } else {
+ $option_setting = get_option( $option );
+ }
+
+ return intval( 'on' == $option_setting );
+ }
+
+ function admin_discussion_likes_settings_field() {
+ $like = $this->admin_likes_get_option( 'social_notifications_like' );
+?>
+ <label><input type="checkbox" id="social_notifications_like" name="social_notifications_like" value="1" <?php checked( $like ); ?> /> <?php esc_html_e( 'Someone likes one of my posts', 'jetpack' ); ?></label>
+<?php
+ }
+
+ function admin_discussion_likes_settings_validate( $input ) {
+ // If it's not set (was unchecked during form submission) or was set to off (during option update), return 'off'.
+ if ( !$input || 'off' == $input )
+ return 'off';
+
+ // Otherwise, return 'on'.
+ return 'on';
+ }
+
+ /**
* The actual options block to be inserted into the sharing page.
*/
function admin_settings_init() { ?>
@@ -403,6 +469,15 @@ class Jetpack_Likes {
</form> <?php
}
+ function admin_init() {
+ add_filter( 'manage_posts_columns', array( $this, 'add_like_count_column' ) );
+ add_filter( 'manage_pages_columns', array( $this, 'add_like_count_column' ) );
+ add_action( 'manage_posts_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
+ add_action( 'manage_pages_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
+ add_action( 'admin_print_styles-edit.php', array( $this, 'load_admin_css' ) );
+ add_action( "admin_print_scripts-edit.php", array( $this, 'enqueue_admin_scripts' ) );
+ }
+
function action_init() {
if ( is_admin() )
return;
@@ -416,22 +491,95 @@ class Jetpack_Likes {
// Comment Likes widget has been disabled, pending performance improvements.
// add_filter( 'comment_text', array( &$this, 'comment_likes' ), 10, 2 );
-
+
if ( $this->in_jetpack ) {
add_filter( 'the_content', array( &$this, 'post_likes' ), 30, 1 );
wp_enqueue_script( 'postmessage', plugins_url( '_inc/postmessage.js', dirname(__FILE__) ), array( 'jquery' ), JETPACK__VERSION, false );
wp_enqueue_script( 'jquery_inview', plugins_url( '_inc/jquery.inview.js', dirname(__FILE__) ), array( 'jquery' ), JETPACK__VERSION, false );
+ wp_enqueue_script( 'jetpack_resize', plugins_url( '_inc/jquery.jetpack-resize.js' , dirname(__FILE__) ), array( 'jquery' ), JETPACK__VERSION, false );
wp_enqueue_style( 'jetpack_likes', plugins_url( 'likes/style.css', __FILE__ ), array(), JETPACK__VERSION );
+
} else {
add_filter( 'post_flair', array( &$this, 'post_likes' ), 30, 1 );
add_filter( 'post_flair_block_css', array( $this, 'post_flair_service_enabled_like' ) );
wp_enqueue_script( 'postmessage', '/wp-content/js/postmessage.js', array( 'jquery' ), JETPACK__VERSION, false );
wp_enqueue_script( 'jquery_inview', '/wp-content/js/jquery/jquery.inview.js', array( 'jquery' ), JETPACK__VERSION, false );
+ wp_enqueue_script( 'jetpack_resize', '/wp-content/js/jquery/jquery.jetpack-resize.js', array( 'jquery' ), JETPACK__VERSION, false );
wp_enqueue_style( 'jetpack_likes', plugins_url( 'jetpack-likes.css', __FILE__ ), array(), JETPACK__VERSION );
}
}
+ /**
+ * Load the CSS needed for the wp-admin area.
+ */
+ function load_admin_css() { ?>
+ <style type="text/css">
+ .fixed .column-likes { width: 5em; padding-top: 8px; text-align: center !important; }
+ .fixed .column-stats { width: 5em; }
+ .fixed .column-likes .post-com-count { background-image: none; }
+ .fixed .column-likes .comment-count { background-color: #888; }
+ .fixed .column-likes .comment-count:hover { background-color: #D54E21; }
+ .admin-color-mp6 .fixed .column-likes .post-com-count::after { border: none !important; }
+ .admin-color-mp6 .fixed .column-likes .comment-count { background-color: #bbb; }
+ .admin-color-mp6 .fixed .column-likes .comment-count:hover { background-color: #2ea2cc; }
+ .admin-color-mp6 .fixed .column-likes .vers img { display: none; }
+ .admin-color-mp6 .fixed .column-likes .vers:before {font:20px/1 dashicons;content: '\f155';-webkit-font-smoothing:antialiased;}
+ </style> <?php
+ }
+
+ /**
+ * Load the JS required for loading the like counts.
+ */
+ function enqueue_admin_scripts() {
+ if ( empty( $_GET['post_type'] ) || 'post' == $_GET['post_type'] || 'page' == $_GET['post_type'] ) {
+ if ( $this->in_jetpack )
+ wp_enqueue_script( 'likes-post-count', plugins_url( 'modules/likes/post-count.js', dirname( __FILE__ ) ), array( 'jquery' ), JETPACK__VERSION );
+ else
+ wp_enqueue_script( 'likes-post-count', plugins_url( 'likes/post-count.js', dirname( __FILE__ ) ), array( 'jquery' ), JETPACK__VERSION );
+ }
+ }
+
+ /**
+ * Add "Likes" column data to the post edit table in wp-admin.
+ *
+ * @param string $column_name
+ * @param int $post_id
+ */
+ function likes_edit_column( $column_name, $post_id ) {
+ if ( 'likes' == $column_name ) {
+
+ if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $blog_id = get_current_blog_id();
+ } else {
+ $jetpack = Jetpack::init();
+ $blog_id = $jetpack->get_option( 'id' );
+ }
+
+ $permalink = get_permalink( get_the_ID() ); ?>
+ <a title="" data-post-id="<?php echo (int) $post_id; ?>" class="post-com-count post-like-count" id="post-like-count-<?php echo (int) $post_id; ?>" data-blog-id="<?php echo (int) $blog_id; ?>" href="<?php echo esc_url( $permalink ); ?>#like-<?php echo (int) $post_id; ?>">
+ <span class="comment-count">0</span>
+ </a>
+ <?php
+ }
+ }
+
+ /**
+ * Add a "Likes" column header to the post edit table in wp-admin.
+ *
+ * @param array $columns
+ * @return array
+ */
+ function add_like_count_column( $columns ) {
+ $date = $columns['date'];
+ unset( $columns['date'] );
+
+ $columns['likes'] = '<span class="vers"><img title="' . esc_attr__( 'Likes', 'jetpack' ) . '" alt="' . esc_attr__( 'Likes', 'jetpack' ) . '" src="//s0.wordpress.com/i/like-grey-icon.png" /></span>';
+ $columns['date'] = $date;
+
+ return $columns;
+ }
+
function post_likes( $content ) {
global $post;
@@ -456,9 +604,15 @@ class Jetpack_Likes {
add_filter( 'wp_footer', array( $this, 'likes_master' ) );
- $src = sprintf( '%1$s://widgets.wp.com/likes/#blog_id=%2$d&post_id=%3$d&origin=%1$s://%4$s', $protocol, $blog_id, $post->ID, $domain );
- $name = sprintf( 'like-post-frame-%1$d-%2$d', $blog_id, $post->ID );
- $wrapper = sprintf( 'like-post-wrapper-%1$d-%2$d', $blog_id, $post->ID );
+ /**
+ * if the same post appears more then once on a page the page goes crazy
+ * we need a slightly more unique id / name for the widget wrapper.
+ */
+ $uniqid = uniqid();
+
+ $src = sprintf( '%1$s://widgets.wp.com/likes/#blog_id=%2$d&amp;post_id=%3$d&amp;origin=%1$s://%4$s&amp;obj_id=%2$d-%3$d-%5$s', $protocol, $blog_id, $post->ID, $domain, $uniqid );
+ $name = sprintf( 'like-post-frame-%1$d-%2$d-%3$s', $blog_id, $post->ID, $uniqid );
+ $wrapper = sprintf( 'like-post-wrapper-%1$d-%2$d-%3$s', $blog_id, $post->ID, $uniqid );
$html = "<div class='sharedaddy sd-block sd-like jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded' id='$wrapper' data-src='$src' data-name='$name'><h3 class='sd-title'>" . esc_html__( 'Like this:', 'jetpack' ) . '</h3>';
$html .= "<div class='post-likes-widget-placeholder' style='height:55px'><span class='button'><span>" . esc_html__( 'Like', 'jetpack' ) . '</span></span> <span class="loading">' . esc_html__( 'Loading...', 'jetpack' ) . '</span></div>';
@@ -493,7 +647,7 @@ class Jetpack_Likes {
add_filter( 'wp_footer', array( $this, 'likes_master' ) );
- $src = sprintf( '%1$s://widgets.wp.com/likes/#blog_id=%2$d&comment_id=%3$d&origin=%1$s://%4$s', $protocol, $blog_id, $comment->comment_ID, $domain );
+ $src = sprintf( '%1$s://widgets.wp.com/likes/#blog_id=%2$d&amp;comment_id=%3$d&amp;origin=%1$s://%4$s', $protocol, $blog_id, $comment->comment_ID, $domain );
$name = sprintf( 'like-comment-frame-%1$d-%2$d', $blog_id, $comment->comment_ID );
$wrapper = sprintf( 'like-comment-wrapper-%1$d-%2$d', $blog_id, $comment->comment_ID );
@@ -532,10 +686,10 @@ class Jetpack_Likes {
}
add_filter( 'wp_footer', array( $this, 'likes_master' ) );
+
+ $src = sprintf( '%1$s://widgets.wp.com/likes/#blog_id=%2$d&amp;post_id=%3$d&amp;origin=%1$s://%4$s', $protocol, $blog_id, $post->ID, $domain );
- $src = sprintf( '%1$s://widgets.wp.com/likes/#blog_id=%2$d&post_id=%3$d&origin=%1$s://%4$s', $protocol, $blog_id, $post->ID, $domain );
-
- $html = "<iframe class='admin-bar-likes-widget jetpack-likes-widget' frameBorder='0' name='admin-bar-likes-widget' src='$src'></iframe>";
+ $html = "<iframe class='admin-bar-likes-widget jetpack-likes-widget' scrolling='no' frameBorder='0' name='admin-bar-likes-widget' src='$src'></iframe>";
$node = array(
'id' => 'admin-bar-likes-widget',
@@ -552,12 +706,12 @@ class Jetpack_Likes {
if ( is_ssl() )
$protocol = 'https';
- $locale = ( '' == get_locale() || 'en' == get_locale() ) ? '' : '&lang=' . strtolower( substr( get_locale(), 0, 2 ) );
- $src = sprintf( '%1$s://widgets.wp.com/likes/master.html?ver=%2$s#ver=%2$s%3$s', $protocol, $this->version, $locale );
+ $locale = ( '' == get_locale() || 'en' == get_locale() ) ? '' : '&amp;lang=' . strtolower( substr( get_locale(), 0, 2 ) );
+ $src = sprintf( '%1$s://widgets.wp.com/likes/master.html?ver=%2$s#ver=%2$s%3$s&amp;mp6=%4$d', $protocol, $this->version, $locale, apply_filters( 'mp6_enabled', 0 ) );
- $likersText = wp_kses( __( '<span>%d</span> bloggers like this:', 'jetpack' ), array( 'span' => array() ) );
+ $likersText = wp_kses( __( '<span>%d</span> bloggers like this:', 'jetpack' ), array( 'span' => array() ) );
?>
- <iframe src='<?php echo $src; ?>' id='likes-master' name='likes-master' style='display:none;'></iframe>
+ <iframe src='<?php echo $src; ?>' scrolling='no' id='likes-master' name='likes-master' style='display:none;'></iframe>
<div id='likes-other-gravatars'><div class="likes-text"><?php echo $likersText; ?></div><ul class="wpl-avatars sd-like-gravatars"></ul></div>
<script type="text/javascript">
//<![CDATA[
@@ -578,7 +732,7 @@ class Jetpack_Likes {
target: target,
type: 'likesMessage',
data: message,
- origin: '*'
+ origin: '*'
} );
}
@@ -628,9 +782,9 @@ class Jetpack_Likes {
var requests = [];
jQuery( '.jetpack-likes-widget-wrapper' ).each( function( i ) {
- var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)/;
+ var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/;
var match = regex.exec( this.id );
- if ( ! match || match.length != 4 )
+ if ( ! match || match.length != 5 )
return;
var info = {
@@ -644,6 +798,8 @@ class Jetpack_Likes {
info.comment_id = match[3];
}
+ info.obj_id = match[4];
+
requests.push( info );
});
@@ -658,8 +814,9 @@ class Jetpack_Likes {
if ( 'showLikeWidget' == event.event ) {
setTimeout( JetpackLikesWidgetQueueHandler, 10 );
jQuery( '#' + event.id + ' .post-likes-widget-placeholder' ).fadeOut( 'fast', function() {
- jQuery( '#' + event.id + ' .post-likes-widget' ).fadeIn( 'fast' );
- JetpackLikespostMessage( { event: 'likeWidgetDisplayed', blog_id: event.blog_id, post_id: event.post_id }, window.frames['likes-master'] );
+ jQuery( '#' + event.id + ' .post-likes-widget' ).fadeIn( 'fast', function() {
+ JetpackLikespostMessage( { event: 'likeWidgetDisplayed', blog_id: event.blog_id, post_id: event.post_id, obj_id: event.obj_id }, window.frames['likes-master'] );
+ });
});
}
@@ -747,8 +904,11 @@ class Jetpack_Likes {
var $wrapper = jQuery( '#' + wrapperID );
$wrapper.find( 'iframe' ).remove();
- $wrapper.find( '.post-likes-widget-placeholder' ).after( "<iframe class='post-likes-widget jetpack-likes-widget' name='" + $wrapper.data( 'name' ) + "' height='55px' width='100%' frameBorder='0' src='" + $wrapper.data( 'src' ) + "'></iframe>" );
-
+ if ( $wrapper.hasClass( 'slim-likes-widget' ) ) {
+ $wrapper.find( '.post-likes-widget-placeholder' ).after( "<iframe class='post-likes-widget jetpack-likes-widget' name='" + $wrapper.data( 'name' ) + "' height='22px' width='68px' frameBorder='0' scrolling='no' src='" + $wrapper.data( 'src' ) + "'></iframe>" );
+ } else {
+ $wrapper.find( '.post-likes-widget-placeholder' ).after( "<iframe class='post-likes-widget jetpack-likes-widget' name='" + $wrapper.data( 'name' ) + "' height='55px' width='100%' frameBorder='0' src='" + $wrapper.data( 'src' ) + "'></iframe>" );
+ }
$wrapper.removeClass( 'jetpack-likes-widget-unloaded' ).addClass( 'jetpack-likes-widget-loading' );
@@ -757,9 +917,14 @@ class Jetpack_Likes {
$wrapper.removeClass( 'jetpack-likes-widget-loading' ).addClass( 'jetpack-likes-widget-loaded' );
JetpackLikespostMessage( { event: 'loadLikeWidget', name: $iframe.attr( 'name' ), width: $iframe.width() }, window.frames[ 'likes-master' ] );
+
+ if ( $wrapper.hasClass( 'slim-likes-widget' ) ) {
+ $wrapper.find( 'iframe' ).Jetpack( 'resizeable' );
+ }
});
+ setTimeout( JetpackLikesWidgetQueueHandler, 250 );
}
- setInterval( JetpackLikesWidgetQueueHandler, 250 );
+ JetpackLikesWidgetQueueHandler();
//]]>
</script>
<?php
@@ -828,6 +993,9 @@ class Jetpack_Likes {
$enabled = $this->is_enabled_sitewide();
}
+ if ( post_password_required() )
+ $enabled = false;
+
/** Other Checks ******************************************************/
// Do not show on excerpts
diff --git a/plugins/jetpack/modules/likes/style.css b/plugins/jetpack/modules/likes/style.css
index 3885cace..ee34f435 100644
--- a/plugins/jetpack/modules/likes/style.css
+++ b/plugins/jetpack/modules/likes/style.css
@@ -15,6 +15,14 @@ div.jetpack-likes-widget-wrapper {
width: 100%;
}
+div.jetpack-likes-widget-wrapper .sd-link-color {
+ font-size: 12px;
+}
+
+div.jetpack-likes-widget-wrapper.slim-likes-widget {
+ width: 1px; /* initial default */
+}
+
#likes-other-gravatars {
display: none;
position: absolute;
@@ -28,6 +36,10 @@ div.jetpack-likes-widget-wrapper {
z-index: 1000;
}
+#likes-other-gravatars * {
+ line-height: normal;
+}
+
#likes-other-gravatars .likes-text {
color: white;
font-size: 14px;
@@ -144,7 +156,7 @@ h3.sd-title {
.post-likes-widget-placeholder .button span:before {
color: #97A8CC;
font-family: "Noticons";
- content: '\2605';
+ content: '\f408';
font-size: 16px;
line-height: 0;
text-shadow: 0 1px 0 #fff;
@@ -164,6 +176,11 @@ h3.sd-title {
float: right;
}
+.slim-likes-widget .post-likes-widget {
+ width: auto;
+ float: none;
+}
+
/* Like Special cases (display on it's own) */
div.sharedaddy.sd-like-enabled .sd-like h3 {
diff --git a/plugins/jetpack/modules/minileven.php b/plugins/jetpack/modules/minileven.php
index e2047e50..89a97d46 100644
--- a/plugins/jetpack/modules/minileven.php
+++ b/plugins/jetpack/modules/minileven.php
@@ -5,6 +5,7 @@
* Module Description: Automatically optimize your site for mobile devices.
* Sort Order: 11
* First Introduced: 1.8
+ * Requires Connection: No
*/
function jetpack_load_minileven() {
diff --git a/plugins/jetpack/modules/minileven/minileven.php b/plugins/jetpack/modules/minileven/minileven.php
index ae2ab016..aa9551c2 100644
--- a/plugins/jetpack/modules/minileven/minileven.php
+++ b/plugins/jetpack/modules/minileven/minileven.php
@@ -306,6 +306,23 @@ function jetpack_mobile_css_settings() {
add_action( 'custom_css_submitbox_misc_actions', 'jetpack_mobile_css_settings' );
+function jetpack_mobile_customizer_controls( $wp_customize ) {
+ $wp_customize->add_setting( 'wp_mobile_custom_css' , array(
+ 'default' => true,
+ 'transport' => 'postMessage',
+ 'type' => 'option'
+ ) );
+
+ $wp_customize->add_control( 'jetpack_mobile_css_control', array(
+ 'type' => 'checkbox',
+ 'label' => __( 'Include this CSS in the Mobile Theme', 'jetpack' ),
+ 'section' => 'jetpack_custom_css',
+ 'settings' => 'wp_mobile_custom_css',
+ ) );
+}
+
+add_action( 'jetpack_custom_css_customizer_controls', 'jetpack_mobile_customizer_controls' );
+
function jetpack_mobile_save_css_settings() {
update_option( 'wp_mobile_custom_css', isset( $_POST['mobile_css'] ) && ! empty( $_POST['mobile_css'] ) );
}
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/content-gallery.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/content-gallery.php
index cf69f252..8db8861b 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/content-gallery.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/content-gallery.php
@@ -10,10 +10,10 @@
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
- <hgroup>
+ <div class="entry-heading">
<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php echo esc_attr( sprintf( __( 'Permalink to %s', 'jetpack' ), the_title_attribute( 'echo=0' ) ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
<h3 class="entry-format"><?php _e( 'Gallery', 'jetpack' ); ?></h3>
- </hgroup>
+ </div>
</header><!-- .entry-header -->
<div class="entry-content">
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/content.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/content.php
index 9ab03516..7d035c29 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/content.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/content.php
@@ -8,11 +8,16 @@
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
+ <?php if ( '1' == get_option( 'wp_mobile_featured_images' ) && is_home() || is_search() || is_archive() ) : ?>
+ <div class="entry-thumbnail">
+ <a href="<?php the_permalink(); ?>" title="<?php echo esc_attr( sprintf( __( 'Permalink to %s', 'jetpack' ), the_title_attribute( 'echo=0' ) ) ); ?>" rel="<?php the_ID(); ?>" class="minileven-featured-thumbnail"><?php the_post_thumbnail(); ?></a>
+ </div><!-- .entry-thumbnail -->
+ <?php endif; ?>
<?php if ( is_sticky() ) : ?>
- <hgroup>
+ <div class="entry-heading">
<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php echo esc_attr( sprintf( __( 'Permalink to %s', 'jetpack' ), the_title_attribute( 'echo=0' ) ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
<h3 class="entry-format"><?php _e( 'Featured', 'jetpack' ); ?></h3>
- </hgroup>
+ <div>
<?php else : ?>
<h1 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php echo esc_attr( sprintf( __( 'Permalink to %s', 'jetpack' ), the_title_attribute( 'echo=0' ) ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h1>
<?php endif; ?>
@@ -30,8 +35,8 @@
</header><!-- .entry-header -->
<div class="entry-content">
- <?php if ( '1' == get_option( 'wp_mobile_excerpt' ) && is_home() || is_search() || is_archive() ) : ?>
- <?php the_excerpt(); ?>
+ <?php if ( '1' == get_option( 'wp_mobile_excerpt' ) && ( is_home() || is_search() || is_archive() ) ) : ?>
+ <?php echo minileven_excerpt( 300 ); ?>
<?php else : ?>
<?php the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'jetpack' ) ); ?>
<?php endif; ?>
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/footer.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/footer.php
index b739fe46..d57b6177 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/footer.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/footer.php
@@ -28,8 +28,6 @@
</div>
</footer><!-- #colophon -->
-
-
<?php wp_footer(); ?>
</body>
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/functions.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/functions.php
index d13cb234..6bd7ee00 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/functions.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/functions.php
@@ -83,6 +83,37 @@ function minileven_scripts() {
}
add_action( 'wp_enqueue_scripts', 'minileven_scripts' );
+function minileven_fonts() {
+
+ /* translators: If there are characters in your language that are not supported
+ by Open Sans, translate this to 'off'. Do not translate into your own language. */
+
+ if ( 'off' !== _x( 'on', 'Open Sans font: on or off', 'minileven' ) ) {
+
+ $opensans_subsets = 'latin,latin-ext';
+
+ /* translators: To add an additional Open Sans character subset specific to your language, translate
+ this to 'greek', 'cyrillic' or 'vietnamese'. Do not translate into your own language. */
+ $opensans_subset = _x( 'no-subset', 'Open Sans font: add new subset (greek, cyrillic, vietnamese)', 'minileven' );
+
+ if ( 'cyrillic' == $opensans_subset )
+ $opensans_subsets .= ',cyrillic,cyrillic-ext';
+ elseif ( 'greek' == $opensans_subset )
+ $opensans_subsets .= ',greek,greek-ext';
+ elseif ( 'vietnamese' == $opensans_subset )
+ $opensans_subsets .= ',vietnamese';
+
+ $protocol = is_ssl() ? 'https' : 'http';
+
+ $opensans_query_args = array(
+ 'family' => 'Open+Sans:200,200italic,300,300italic,400,400italic,600,600italic,700,700italic',
+ 'subset' => $opensans_subsets,
+ );
+ wp_register_style( 'minileven-open-sans', add_query_arg( $opensans_query_args, "$protocol://fonts.googleapis.com/css" ), array(), null );
+ }
+}
+add_action( 'init', 'minileven_fonts' );
+
/**
* Register our sidebars and widgetized areas.
* @since Minileven 1.0
@@ -104,17 +135,16 @@ function minileven_posts_per_page() {
}
add_filter('pre_option_posts_per_page', 'minileven_posts_per_page');
-/* This function determines the actual theme the user is using. */
+/**
+ * Determine the currently active theme.
+ */
function minileven_actual_current_theme() {
- if ( function_exists( 'jetpack_mobile_template' ) )
- remove_action( 'option_template', 'jetpack_mobile_template' );
-
- $template = get_option( 'template' );
+ $removed = remove_action( 'option_stylesheet', 'jetpack_mobile_stylesheet' );
+ $stylesheet = get_option( 'stylesheet' );
+ if ( $removed )
+ add_action( 'option_stylesheet', 'jetpack_mobile_stylesheet' );
- if ( function_exists( 'jetpack_mobile_template' ) )
- add_action( 'option_template', 'jetpack_mobile_template' );
-
- return $template;
+ return $stylesheet;
}
/* This function grabs the location of the custom menus from the current theme. If no menu is set in a location
@@ -149,4 +179,10 @@ function minileven_get_background() {
/**
* Implement the Custom Header functions
*/
-require( get_template_directory() . '/inc/custom-header.php' ); \ No newline at end of file
+require( get_template_directory() . '/inc/custom-header.php' );
+
+/**
+ * If the user has set a static front page, show all posts on the front page, instead of a static page.
+ */
+if ( '1' == get_option( 'wp_mobile_static_front_page' ) )
+ add_filter( 'pre_option_page_on_front', '__return_zero' ); \ No newline at end of file
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/header.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/header.php
index 7c5f9a66..1b7cad92 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/header.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/header.php
@@ -18,25 +18,21 @@
<body <?php body_class(); ?>>
<div id="wrapper">
-<div id="page" class="hfeed">
- <header id="branding" role="banner">
<?php
- minileven_header();
$location = minileven_get_menu_location(); // get the menu locations from the current theme in use
?>
<div class="menu-search">
- <nav id="access" role="navigation">
- <div class="menu-handle">
- <h3 class="assistive-text"><?php _e( 'Menu', 'jetpack' ); ?></h3>
- </div><!-- .menu-handle -->
+ <nav id="access" class="site-navigation main-navigation" role="navigation">
+ <h3 class="menu-toggle"><?php _e( 'Menu', 'jetpack' ); ?></h3>
+
<?php /* Allow screen readers / text browsers to skip the navigation menu and get right to the good stuff. */ ?>
<div class="skip-link"><a class="assistive-text" href="#content" title="<?php esc_attr_e( 'Skip to primary content', 'jetpack' ); ?>"><?php _e( 'Skip to primary content', 'minileven' , 'jetpack'); ?></a></div>
<?php /* Our navigation menu. If one isn't filled out, wp_nav_menu falls back to wp_page_menu. The menu assiged to the primary position is the one used. If none is assigned, the menu with the lowest ID is used. */
if ( false !== $location ) :
$menu_id = array_shift( array_values( $location ) ); // acccess the ID of the menu assigned to that location. Using only the first menu ID returned in the array.
- wp_nav_menu( array( 'theme_location' => 'primary', 'menu' => $menu_id ) );
+ wp_nav_menu( array( 'theme_location' => 'primary', 'container_class' => '', 'menu_class' => 'nav-menu', 'menu' => $menu_id ) );
else: // if the $location variable is false, wp_page_menu() is shown instead.
- wp_nav_menu( array( 'theme_location' => 'primary' ) );
+ wp_nav_menu( array( 'theme_location' => 'primary', 'container_class' => '', 'menu_class' => 'nav-menu' ) );
endif;
?>
</nav><!-- #access -->
@@ -44,6 +40,8 @@
<?php get_search_form(); ?>
</div><!-- .search-form-->
</div><!-- .menu-search-->
- </header><!-- #branding -->
- <div id="main"> \ No newline at end of file
+ <?php minileven_header(); ?>
+
+ <div id="page" class="hfeed">
+ <div id="main"> \ No newline at end of file
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/image.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/image.php
index be8402bd..30f57195 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/image.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/image.php
@@ -85,7 +85,7 @@ get_header(); ?>
<nav id="nav-single">
<h3 class="assistive-text"><?php _e( 'Image navigation', 'next-saturday' , 'jetpack' ); ?></h3>
- <span class="nav-previous"><?php previous_image_link( false, __( '&raquo; Previous' , 'jetpack' ) ); ?></span>
+ <span class="nav-previous"><?php previous_image_link( false, __( '&laquo; Previous' , 'jetpack' ) ); ?></span>
<span class="nav-next"><?php next_image_link( false, __( 'Next &raquo; ' , 'jetpack' ) ); ?></span>
</nav><!-- #nav-single -->
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/custom-header.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/custom-header.php
index 8a7a21e8..dc8758b7 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/custom-header.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/custom-header.php
@@ -31,20 +31,25 @@ function minileven_header() {
$header_image = minileven_get_header_image();
$header_text = minileven_header_text_display();
- if ( 'blank' != $header_text ) : ?>
- <hgroup>
- <h1 id="site-title"><span><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></span></h1>
- <h2 id="site-description"><?php bloginfo( 'description' ); ?></h2>
- </hgroup>
-<?php endif;
-
- if ( false !== $header_image ) : ?>
- <div id="header-img">
- <a href="<?php echo esc_url( home_url( '/' ) ); ?>">
- <img src="<?php echo $header_image; ?>" alt="" />
- </a>
- </div><!-- #header-img -->
-<?php endif; // end check for header image existence.
+ if ( 'blank' != $header_text || false != $header_image ) : ?>
+
+ <header id="branding" role="banner">
+ <?php if ( 'blank' != $header_text ) : ?>
+ <div class="site-branding">
+ <h1 id="site-title"><span><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></span></h1>
+ <h2 id="site-description"><?php bloginfo( 'description' ); ?></h2>
+ </div>
+ <?php endif;
+
+ if ( false !== $header_image ) : ?>
+ <div id="header-img">
+ <a href="<?php echo esc_url( home_url( '/' ) ); ?>">
+ <img src="<?php echo $header_image; ?>" alt="" />
+ </a>
+ </div><!-- #header-img -->
+ <?php endif; // end check for header image existence. ?>
+ </header><!-- #branding -->
+<?php endif; // end check for both header text and header image
}
/* This function displays the custom background image or color, and custom text color */
@@ -82,7 +87,8 @@ function minileven_show_background_and_header_color() {
<?php echo trim( $style ); ?>
}
<?php } ?>
- #page {
+ #page,
+ #branding {
margin: 0.6em 0.6em 0.8em;
}
#site-generator {
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/template-tags.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/template-tags.php
index 2fc5f6d6..6a398391 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/template-tags.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/template-tags.php
@@ -62,8 +62,6 @@ function minileven_comment( $comment, $args, $depth ) {
)
);
?>
-
- <?php edit_comment_link( __( 'Edit', 'jetpack' ), '<span class="edit-link">', '</span>' ); ?>
</div><!-- .comment-author .vcard -->
<?php if ( $comment->comment_approved == '0' ) : ?>
@@ -74,9 +72,8 @@ function minileven_comment( $comment, $args, $depth ) {
</footer>
<div class="comment-content"><?php comment_text(); ?></div>
-
<div class="reply">
- <?php comment_reply_link( array_merge( $args, array( 'reply_text' => __( 'Reply <span>&darr;</span>', 'jetpack' ), 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
+ <?php comment_reply_link( array_merge( $args, array( 'reply_text' => __( 'Reply', 'jetpack' ), 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
</div><!-- .reply -->
</article><!-- #comment-## -->
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/tweaks.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/tweaks.php
index 35a96720..8bbaf4da 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/tweaks.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/inc/tweaks.php
@@ -9,21 +9,25 @@
*/
/**
- * Sets the post excerpt length to 40 words.
- *
- * To override this length in a child theme, remove the filter and add your own
- * function tied to the excerpt_length filter hook.
- */
-function minileven_excerpt_length( $length ) {
- return 40;
+* Sets the post excerpt length based on number of characters, without breaking words at the end
+*
+*/
+function minileven_excerpt( $count ) {
+ $excerpt = get_the_content();
+ $excerpt = strip_tags( $excerpt );
+ $excerpt = strip_shortcodes( $excerpt );
+ $excerpt = substr( $excerpt, 0, $count );
+ $excerpt = substr( $excerpt, 0, strripos( $excerpt, " " ) );
+ $excerpt = $excerpt . minileven_continue_reading_link();
+ return $excerpt;
}
-add_filter( 'excerpt_length', 'minileven_excerpt_length' );
+/**
/**
* Returns a "Continue Reading" link for excerpts
*/
function minileven_continue_reading_link() {
- return ' <a href="'. esc_url( get_permalink() ) . '">' . __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'jetpack' ) . '</a>';
+ return ' &hellip; <a href="'. esc_url( get_permalink() ) . '">' . __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'jetpack' ) . '</a>';
}
/**
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/index.php b/plugins/jetpack/modules/minileven/theme/pub/minileven/index.php
index 71aa73b6..9821b6d6 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/index.php
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/index.php
@@ -70,4 +70,6 @@ get_header(); ?>
<?php minileven_content_nav( 'nav-below' ); ?>
</div><!-- #primary -->
+
+<?php get_sidebar(); ?>
<?php get_footer(); ?> \ No newline at end of file
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/js/small-menu.js b/plugins/jetpack/modules/minileven/theme/pub/minileven/js/small-menu.js
index f6e1d060..7eaf1e33 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/js/small-menu.js
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/js/small-menu.js
@@ -1,41 +1,33 @@
/**
- * Handles toggling the main navigation menu for small screens.
+ * navigation.js
+ *
+ * Handles toggling the navigation menu for small screens.
*/
-jQuery( document ).ready( function( $ ) {
- var $subsidiary = $( '#branding' ),
- timeout = false;
+( function() {
+ var nav = document.getElementById( 'access' ), button, menu;
+ if ( ! nav )
+ return;
+ button = nav.getElementsByTagName( 'h3' )[0];
+ menu = nav.getElementsByTagName( 'ul' )[0];
+ if ( ! button )
+ return;
- $.fn.smallMenu = function() {
- $subsidiary.find( '#access' ).addClass( 'main-small-navigation' );
- $subsidiary.find( '#access h3' ).removeClass( 'assistive-text' ).addClass( 'menu-label' );
- $subsidiary.find( '#access .menu-handle' ).addClass( 'menu-toggle' );
+ // Hide button if menu is missing or empty.
+ if ( ! menu || ! menu.childNodes.length ) {
+ button.style.display = 'none';
+ return;
+ }
- $( '.menu-toggle' ).click( function() {
- $subsidiary.find( '.menu' ).toggle();
- $( this ).toggleClass( 'toggled-on' );
- } );
- };
-
- // Check viewport width on first load.
- if ( $( window ).width() < 4000 )
- $.fn.smallMenu();
-
- // Check viewport width when user resizes the browser window.
- $( window ).resize( function() {
- var browserWidth = $( window ).width();
+ button.onclick = function() {
+ if ( -1 == menu.className.indexOf( 'nav-menu' ) )
+ menu.className = 'nav-menu';
- if ( false !== timeout )
- clearTimeout( timeout );
-
- timeout = setTimeout( function() {
- if ( browserWidth < 4000 ) {
- $.fn.smallMenu();
- } else {
- $subsidiary.find( '#access' ).removeClass( 'main-small-navigation' );
- $subsidiary.find( '#access h3' ).removeClass( 'menu-label' ).addClass( 'assistive-text' );
- $subsidiary.find( '#access .menu-handle' ).removeClass( 'menu-toggle' );
- $subsidiary.find( '.menu' ).removeAttr( 'style' );
- }
- }, 200 );
- } );
-} ); \ No newline at end of file
+ if ( -1 != button.className.indexOf( 'toggled-on' ) ) {
+ button.className = button.className.replace( ' toggled-on', '' );
+ menu.className = menu.className.replace( ' toggled-on', '' );
+ } else {
+ button.className += ' toggled-on';
+ menu.className += ' toggled-on';
+ }
+ };
+} )(); \ No newline at end of file
diff --git a/plugins/jetpack/modules/minileven/theme/pub/minileven/style.css b/plugins/jetpack/modules/minileven/theme/pub/minileven/style.css
index 692a8f4f..e70415be 100644
--- a/plugins/jetpack/modules/minileven/theme/pub/minileven/style.css
+++ b/plugins/jetpack/modules/minileven/theme/pub/minileven/style.css
@@ -10,6 +10,27 @@ License URI: license.txt
Tags: dark, light, white, black, gray, one-column, flexible-width, responsive-width, custom-background, custom-header, custom-menu, full-width-template, infinite-scroll, microformats, post-formats, rtl-language-support, sticky-post, theme-options, translation-ready, blog, bright, clean, contemporary, elegant, minimal, modern, photography, simple, tumblelog
*/
+.image-attachment .entry-caption p {
+ font-size: 0.769em;
+ letter-spacing: 0.1em;
+ line-height: 2.6;
+ margin: 0 0 2.6em;
+ text-transform: uppercase;
+}
+
+/* =Webfont, thanks to FontSquirrel.com for conversion!
+-------------------------------------------------------------- */
+@font-face {
+ font-family: 'Genericons';
+ src: url('inc/fonts/genericons-regular-webfont.eot');
+ src: url('inc/fonts/genericons-regular-webfont.eot?#iefix') format('embedded-opentype'),
+ url('inc/fonts/genericons-regular-webfont.woff') format('woff'),
+ url('inc/fonts/genericons-regular-webfont.ttf') format('truetype'),
+ url('inc/fonts/genericons-regular-webfont.svg#genericonsregular') format('svg');
+ font-weight: normal;
+ font-style: normal;
+
+}
/* =Reset default browser CSS. Based on work by Eric Meyer: http://meyerweb.com/eric/tools/css/reset/index.html
-------------------------------------------------------------- */
@@ -47,7 +68,7 @@ a img {
border: 0;
}
article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
+footer, header, menu, nav, section {
display: block;
}
@@ -56,16 +77,21 @@ footer, header, hgroup, menu, nav, section {
----------------------------------------------- */
body, input, textarea {
- color: #373737;
- font: 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #404040;
+ font: 13px "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
line-height: 1.625;
word-wrap: break-word;
}
body {
- background: #eee;
+ background: #f1f1f1;
+ font-weight: 400;
}
-#page {
+#page,
+#branding {
background: #fff;
+ -moz-box-shadow: 0 1px 2px rgba( 0,0,0,0.075 );
+ -webkit-box-shadow: 0 1px 2px rgba( 0,0,0,0.075 );
+ box-shadow: 0 1px 2px rgba( 0,0,0,0.075 );
}
/* Headings */
@@ -111,7 +137,6 @@ cite, em, i {
font-style: italic;
}
blockquote {
- font-family: Georgia, "Bitstream Charter", serif;
font-style: italic;
font-weight: normal;
margin: 0;
@@ -192,18 +217,34 @@ input[type=email] {
input#s {
border-radius: 2px;
height: 1.692em;
- line-height: 1.2em;
- padding: 0.4em 0.6em;
+ line-height: 1.2;
+ padding: 0.4em 0.6em 0.29em;
+}
+input#s:focus {
+ padding-bottom: 0.3em;
}
input#searchsubmit {
display: none;
}
+input#s:focus,
+input[type=text]:focus,
+input[type=email]:focus,
+textarea:focus {
+ font-size: 1.231em;
+}
/* Links */
a {
- color: #00a4bc;
+ color: #278dbc;
text-decoration: none;
}
+a:hover,
+.entry-title a:hover,
+.entry-meta .edit-link a:hover,
+.commentlist .edit-link a:hover,
+.entry-meta .comments-link a:hover {
+ color: #7dcae7;
+}
/* Assistive text */
.assistive-text {
clip: rect(1px, 1px, 1px, 1px);
@@ -219,12 +260,19 @@ a {
margin: 0 auto;
padding: 2.5%;
}
+#branding {
+ margin: 0.6em auto 0;
+ padding: 2.5% 2.5% 1.5%;
+}
#primary,
#secondary {
margin: 0 auto;
width: auto;
}
+#secondary {
+ margin-top: 0.8em;
+}
/* Alignment */
.aligncenter,
@@ -240,7 +288,6 @@ a {
embed,
iframe,
object {
- height: auto;
width: auto;
}
@@ -248,7 +295,7 @@ object {
/* =Header
----------------------------------------------- */
-#branding hgroup {
+#branding .site-branding {
margin-bottom: 1.3em;
}
#site-title,
@@ -259,7 +306,7 @@ object {
color: #111;
font-size: 1.846em;
font-weight: bold;
- line-height: 1.3em;
+ line-height: 1.3;
}
#site-description {
color: #7a7a7a;
@@ -280,13 +327,12 @@ header img {
----------------------------------------------- */
.menu-search {
- background: #dcdcdc;
- background: -moz-linear-gradient(#dcdcdc, #c8c8c8);
- background: -o-linear-gradient(#dcdcdc, #c8c8c8);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#dcdcdc), to(#c8c8c8)); /* older webkit syntax */
- background: -webkit-linear-gradient(#dcdcdc, #c8c8c8);
+ background: #1e8cbe;
+ -webkit-box-shadow: inset 0 -1px rgba(0, 86, 132, 0.8), 0 1px 3px rgba(0, 86, 132, 0.4);
+ -moz-box-shadow: inset 0 -1px 0 rgba(0, 86, 132, 0.8), 0 1px 3px rgba(0, 86, 132, 0.4);
+ box-shadow: inset 0 -1px 0 rgba(0, 86, 132, 0.8), 0 1px 3px rgba(0, 86, 132, 0.4);
clear: both;
- margin-bottom: 1.3em;
+ height: 46px;
width: 100%;
}
.menu-search:after {
@@ -294,35 +340,44 @@ header img {
content: "";
display: block;
}
+.menu-search,
+#access,
+.menu-toggle,
+#access .menu-label {
+ height: 46px;
+}
/* Small menu */
#access {
float: left;
- width: 55%;
+ width: 60%;
}
.search-form {
float: right;
text-align: right;
- width: 43%;
+ width: 39%;
}
.menu-toggle {
cursor: pointer;
}
-#access .toggled-on {
- background-color: #F1F1F1;
- background-image: -ms-linear-gradient(top,#f9f9f9,#ececec);
- background-image: -moz-linear-gradient(top,#f9f9f9,#ececec);
- background-image: -o-linear-gradient(top,#f9f9f9,#ececec);
- background-image: -webkit-gradient(linear,left top,left bottom,from(#f9f9f9),to(#ececec));
- background-image: -webkit-linear-gradient(top,#f9f9f9,#ececec);
- background-image: linear-gradient(top,#f9f9f9,#ececec);
- border: 1px solid #e9e9e9;
- border-bottom-width: 0;
- box-shadow: 0 1px 0 #fff;
+#access h3.toggled-on {
+ opacity: 0.8;
}
-.main-small-navigation {
- position: relative;
- z-index: 99999;
+#access {
+ position: relative;
+ z-index: 99999;
+ }
+#access ul.nav-menu {
+ background: #fff;
+ -webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.15), 0 3px 8px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: 0 0 2px rgba(0, 0, 0, 0.15), 0 3px 8px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 0 2px rgba(0, 0, 0, 0.15), 0 3px 8px rgba(0, 0, 0, 0.1);
+ display: none;
+ position: absolute;
+ left: 0.5em;
+ top: 3em;
+ width: 100%;
+ z-index: 99999;
}
.main-small-navigation .menu {
background: #f9f9f9;
@@ -330,65 +385,74 @@ header img {
position: absolute;
width: 100%;
}
-.main-small-navigation ul li {
- border-bottom: 1px solid #e9e9e9;
- padding: 0.5em 0.8em;
-}
-.main-small-navigation ul li:last-of-type {
- border: none;
-}
-.main-small-navigation ul ul li,
-.main-small-navigation ul ul ul li {
- border: none;
- padding-bottom: 0;
-}
-.main-small-navigation a {
- color: #373737;
+#access ul.nav-menu:before {
+ color: #fff;
+ content: '\f500';
+ display: inline-block;
+ font: 0.9em/1 'Genericons';
+ left: 49px;
+ position: absolute;
+ top: -11px;
+ }
+#access ul li {
+ border-bottom: 1px solid rgba( 0, 0, 0, 0.1 );
+ padding: 1em 0.8em;
+}
+#access ul li:last-of-type {
+ border: none;
+}
+#access ul ul li,
+#access ul ul ul li {
+ border: none;
+ padding-bottom: 0;
+}
+#access a {
display: block;
- font-size: 0.923em;
- font-weight: bold;
+ font-size: 1em;
}
-.main-small-navigation ul {
+#access ul {
+ display: none;
list-style: none;
margin: 0;
padding: 0.5em 0;
}
-.main-small-navigation .sub-menu {
+#access ul ul {
+ display: block;
+}
+#access .sub-menu {
margin: 0 0 0 15px;
}
-#access .menu-label {
+#access .menu-toggle {
clear: none;
+ color: #fff;
font-size: 1.077em;
- font-weight: bold;
- line-height: 2.5em;
- padding-left: 0.8em;
- text-shadow: 0 1px 0 #fff;
+ line-height: 2.5;
+ padding: 0.3em 0 0 0.8em;
}
-#access .menu-label:after {
- color: #999;
- content: "+";
+#access .menu-toggle:after {
+ content: '\f502';
cursor: pointer;
- font-size: 1em;
- font-weight: bold;
- margin-left: 0.5em;
- width: 18px;
- height: 18px;
- text-shadow: 0 1px 0 #fff;
+ display: inline-block;
+ font: 0.7em/1 'Genericons';
+ margin-left: 0.8em;
+ margin-top: 1.7em;
+ position: absolute;
}
-#access .toggled-on .menu-label:after {
- content: "-";
+#access .toggled-on:after {
+ opacity: 0.8;
}
-.main-small-navigation .menu {
- display: none;
+#access ul.nav-menu.toggled-on {
+ display: inline-block;
}
.search-form #s {
- background: #eee;
- border: 1px solid #ddd;
+ background: #006d9d;
+ border: 1px solid #00587f;
+ border-width: 0 0 0 1px;
border-radius: 0;
- color: #888;
- font-size: 0.923em;
- margin-right: 1%;
- text-shadow: 0 1px 0 #fff;
+ color: rgba( 255, 255, 255, 0.6 );
+ font-size: 1em;
+ height: 30px;
+ margin-right: 0;
padding: 0.6em;
width: 80%;
}
@@ -400,9 +464,10 @@ header img {
.page-title {
color: #666;
font-size: 0.769em;
- font-weight: 500;
+ font-weight: 300;
letter-spacing: 0.1em;
- line-height: 2.6em;
+ line-height: 2.6;
+ margin-bottom: 1.2em;
text-transform: uppercase;
}
.page-title a {
@@ -419,7 +484,7 @@ header img {
position: relative;
}
.hentry {
- border-bottom: 1px solid #ddd;
+ border-bottom: 1px solid #ececec;
}
.hentry:last-child,
.no-results,
@@ -433,11 +498,8 @@ body.singular .hentry {
}
.entry-title {
clear: both;
- color: #222;
- font-size: 1.615em;
- font-weight: bold;
- line-height: 1.5em;
- padding-bottom: .3em;
+ font-size: 1.538em;
+ line-height: 1.260;
word-wrap: break-word;
}
.featured-post .entry-title {
@@ -445,37 +507,97 @@ body.singular .hentry {
}
.entry-title,
.entry-title a {
- color: #222;
+ color: #333;
text-decoration: none;
}
.entry-meta {
color: #666;
clear: both;
font-size: 0.923em;
- line-height: 1.385em;
+ font-weight: 300;
+ line-height: 1.385;
overflow: hidden;
padding: 0 0 0.6em 0;
}
-.entry-meta a {
- font-weight: bold;
+.entry-meta .entry-date,
+.entry-meta .entry-gallery {
+ display: block;
+ float: left;
+}
+.entry-meta .author-link {
+ display: block;
+ margin-top: 0.7em;
+}
+.entry-meta .comments-link {
+ display: block;
+ float: right;
+}
+.entry-meta .edit-link a {
+ margin-right: .5em;
+}
+.entry-meta .edit-link a,
+.commentlist .edit-link a,
+.entry-meta .comments-link a,
+a.comment-reply-link {
+ color: #464646;
+}
+.entry-meta .edit-link a {
+ float: right;
+ text-decoration: none;
+ padding: 0 0.615em;
+}
+.entry-meta .comments-link a:before,
+.entry-meta .edit-link a:before {
+ display: inline-block;
+ -webkit-font-smoothing: antialiased;
+ font: normal 18px/1 'Genericons';
+ margin-right: 0.1em;
+ vertical-align: top;
+}
+.entry-meta .comments-link a:before {
+ content: '\f300';
+ font-family: Genericons;
+}
+.entry-meta .edit-link a:before,
+.commentlist .edit-link a:before {
+ content: '\f411';
+ font-family: Genericons;
+}
+.commentlist .edit-link a:before,
+.entry-meta .comments-link a:before,
+.entry-meta .edit-link a:before,
+a.comment-reply-link:before {
+ color: #7bcbe4;
}
.entry-content {
+ font-size: 1em;
+ line-height: 1.538;
+ margin: 1.286em 0;
padding: 0;
}
.entry-content h1,
.entry-content h2,
.comment-content h1,
-.comment-content h2 {
+.comment-content h2,
+.entry-content h3,
+.comment-content h3 {
color: #000;
- font-weight: bold;
margin: 0 0 .8125em;
}
+.entry-content h1,
+.comment-content h1 {
+ font-size: 1.5em;
+ line-height: 2.9;
+}
+.entry-content h2,
+.comment-content h2 {
+ font-size: 1.4em;
+ line-height: 2.6;
+}
.entry-content h3,
.comment-content h3 {
- font-size: 0.769em;
- letter-spacing: 0.1em;
- line-height: 2.6em;
- text-transform: uppercase;
+ font-size: 1.3em;
+ line-height: 2.3;
}
.entry-content table,
.comment-content table {
@@ -489,7 +611,7 @@ body.singular .hentry {
font-size: 0.769em;
font-weight: 500;
letter-spacing: 0.1em;
- line-height: 2.6em;
+ line-height: 2.6;
text-transform: uppercase;
}
.entry-content td,
@@ -519,44 +641,15 @@ dl.gallery-item {
margin: 0 0 1em;
}
.page-link a {
- background: #eee;
- color: #373737;
+ background: #278dbc;
+ color: #fff;
margin: 0;
- padding: 0.154em 0.231em;
+ padding: 0.1em 0.231em;
text-decoration: none;
}
.page-link span {
margin-right: 0.462em;
}
-.entry-meta .entry-date,
-.entry-meta .entry-gallery {
- display: block;
- float: left;
-}
-.entry-meta .comments-link {
- display: block;
- float: right;
-}
-.entry-meta .edit-link a {
- margin-right: .5em;
-}
-.entry-meta .edit-link a,
-.commentlist .edit-link a {
- background: #eee;
- -moz-border-radius: 3px;
- border-radius: 3px;
- color: #666;
- float: right;
- font-size: 1em;
- font-weight: normal;
- line-height: 1.5em;
- text-decoration: none;
- padding: 0 0.615em;
-}
-.entry-content .edit-link {
- clear: both;
- display: block;
-}
/* Images */
.entry-content img,
@@ -565,7 +658,7 @@ dl.gallery-item {
display: block;
height: auto;
margin: 0 auto;
- max-width: 100%; /* Fluid images for posts, comments, and widgets */
+ max-width: 100% !important; /* Fluid images for posts, comments, and widgets */
}
#content .gallery-columns-3 .gallery-item img,
#content .gallery-columns-4 .gallery-item img,
@@ -609,8 +702,7 @@ p img,
}
.wp-caption .wp-caption-text,
.gallery-caption {
- color: #666;
- font-family: Georgia, serif;
+ color: #999;
font-size: 0.923em;
}
.wp-caption .wp-caption-text {
@@ -664,17 +756,24 @@ and remove the padding rules below.
*/
.entry-header .entry-format {
color: #666;
- font-size: 10px;
- font-weight: 500;
+ font-size: 0.7em;
+ font-weight: 300;
letter-spacing: 0.1em;
- line-height: 2.6em;
+ line-height: 2em;
position: absolute;
text-transform: uppercase;
top: -5px;
}
-.entry-header hgroup .entry-title {
+.entry-header .entry-heading .entry-title {
padding-top: 0.8em;
}
+.entry-header .entry-heading {
+ position: relative;
+}
+.entry-thumbnail {
+ margin-bottom: 0.7em;
+ text-align: center;
+}
/* Singular content styles for Posts and Pages */
.singular .hentry {
@@ -798,13 +897,6 @@ and remove the padding rules below.
border-color: #ddd;
background: #fff;
}
-.image-attachment .entry-caption p {
- font-size: 0.769em;
- letter-spacing: 0.1em;
- line-height: 2.6em;
- margin: 0 0 2.6em;
- text-transform: uppercase;
-}
/* =Navigation
@@ -815,7 +907,7 @@ and remove the padding rules below.
}
#nav-below,
#nav-single {
- margin: 0 auto 0.6em;
+ margin: 0 auto 1.9em;
overflow: hidden;
width: 100%;
}
@@ -841,12 +933,11 @@ and remove the padding rules below.
}
.nav-previous a,
.nav-next a {
- background: #00a4bc;
+ background: #278dbc;
color: #fff;
display: block;
font-size: 1.231em;
- font-weight: bold;
- padding: 1.2em 0;
+ padding: 1em 0;
text-align: center;
width: 100%;
}
@@ -868,29 +959,34 @@ and remove the padding rules below.
color: #666;
font-size: 0.923em;
padding: .6em 0.8em;
+ -moz-box-shadow: 0 1px 2px rgba( 0,0,0,0.075 );
+ -webkit-box-shadow: 0 1px 2px rgba( 0,0,0,0.075 );
+ box-shadow: 0 1px 2px rgba( 0,0,0,0.075 );
}
.widget {
border-bottom: 1px solid #ddd;
clear: both;
margin: 0;
- padding: 1.625em 0;
+ overflow: hidden;
+ padding: 1em 0;
}
.widget:last-of-type {
border: 0;
}
.widget-title {
color: #666;
- font-size: 0.833em;
- letter-spacing: 0.1em;
+ font-size: 1.2em;
+ font-weight: bold;
line-height: 2em;
margin-bottom: 0.5em;
- text-transform: uppercase;
}
.widget-title a {
color: #666;
}
.widget ul {
+ list-style: none;
margin-bottom: 0;
+ margin-left: 0;
}
.widget ul ul {
margin-left: 1.5em;
@@ -899,7 +995,7 @@ and remove the padding rules below.
color: #777;
}
.widget a {
- font-weight: bold;
+ font-weight: normal;
text-decoration: none;
}
.widget a:hover,
@@ -924,7 +1020,7 @@ and remove the padding rules below.
top: -2px;
}
.widget_search #searchsubmit:active {
- background: #00a4bc;
+ background: #278dbc;
border-color: #0861a5;
-webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.1);
-moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.1);
@@ -1025,7 +1121,7 @@ and remove the padding rules below.
#flickr_badge_uber_wrapper a:link,
#flickr_badge_uber_wrapper a:active,
#flickr_badge_uber_wrapper a:visited {
- color: #00a4bc !important;
+ color: #278dbc !important;
}
@@ -1055,14 +1151,15 @@ and remove the padding rules below.
}
.commentlist {
list-style: none;
- margin: 0 auto;
+ margin: 2em auto;
width: 100%;
}
.commentlist > li.comment {
- background: #f6f6f6;
- border: 1px solid #ddd;
- border-width: 1px 0;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-width: 1px 0 0;
+ clear: both;
margin: 0 -2.5% 0.5em;
+ overflow: hidden;
padding: .8em;
position: relative;
}
@@ -1090,26 +1187,28 @@ and remove the padding rules below.
.commentlist .reblog p:first-child a {
font-weight: bold;
}
-.commentlist .pingback,
+.commentlist .pingback {
+ border-top: 1px solid rgba( 0, 0, 0, 0.1 );
+ margin: 0 -2.5% 0.5em;
+}
.commentlist .pingback p {
- margin: 0 0 .8em;
+ color: #c0c0c0;
+ margin-bottom: 0;
+ padding: 0.8em;
}
.commentlist .children {
list-style: none;
margin: 0;
}
.commentlist .children li.comment {
- background: #fff;
- border-left: 1px solid #ddd;
- -moz-border-radius: 0 3px 3px 0;
- border-radius: 0 3px 3px 0;
+ background: #f9f9f9;
+ border-top: 1px solid rgba( 0, 0, 0, 0.1 );
+ clear: both;
margin: 1.625em 0 0;
- padding: 1.625em;
+ overflow: hidden;
+ padding: 1.625em 1.625em 0.5em;
position: relative;
}
-.commentlist .children li.comment .fn {
- display: block;
-}
.comment-meta .fn {
font-style: normal;
}
@@ -1118,21 +1217,17 @@ and remove the padding rules below.
margin-left: 4em;
}
.comment-meta {
- color: #666;
font-size: 0.923em;
}
.comment-content {
- padding-top: 0.2em;
+ margin-top: 1em;
}
.commentlist .children li.comment .comment-meta {
- line-height: 1.625em;
+ line-height: 1.625;
margin-left: 3.462em;
}
.commentlist .children li.comment .comment-content {
- margin: 1.625em 0 0;
-}
-.comment-meta a {
- font-weight: bold;
+ margin: 1em 0 0 3.1em;
}
.comment-meta a:focus,
.comment-meta a:active,
@@ -1140,8 +1235,6 @@ and remove the padding rules below.
}
.commentlist .avatar {
background: transparent;
- -moz-border-radius: 3px;
- border-radius: 3px;
display: block;
padding: 0;
position: absolute;
@@ -1158,46 +1251,31 @@ and remove the padding rules below.
position: absolute;
top: 2.2em;
}
+.comment-actions {
+ float: right;
+ font-weight: 300;
+ margin-bottom: 1em;
+}
+a.comment-reply-link:before {
+ content: '\f412';
+ display: inline-block;
+ -webkit-font-smoothing: antialiased;
+ font: normal 13px/1 'Genericons';
+ margin: 0.2em 0.1em 0 0;
+ vertical-align: top;
+}
a.comment-reply-link {
- background: #eee;
- -moz-border-radius: 3px;
- border-radius: 3px;
- color: #666;
display: inline-block;
font-size: 0.923em;
padding: 0 0.615em;
text-decoration: none;
}
-a.comment-reply-link:hover,
-a.comment-reply-link:focus,
-a.comment-reply-link:active {
- background: #888;
- color: #fff;
-}
a.comment-reply-link > span {
display: inline-block;
position: relative;
top: -1px;
}
-/* Post author highlighting */
-.commentlist > li.bypostauthor {
- background: #ddd;
- border-color: #d3d3d3;
-}
-.commentlist > li.bypostauthor .comment-meta {
- color: #575757;
-}
-.commentlist > li.bypostauthor .comment-meta a:focus,
-.commentlist > li.bypostauthor .comment-meta a:active,
-.commentlist > li.bypostauthor .comment-meta a:hover {
-}
-/* Post Author threaded comments */
-.commentlist .children > li.bypostauthor {
- background: #ddd;
- border-color: #d3d3d3;
-}
-
/* Comment Form */
#respond {
margin: 0 auto 1.625em;
@@ -1219,10 +1297,8 @@ a.comment-reply-link > span {
#respond .comment-form-email label,
#respond .comment-form-url label,
#respond .comment-form-comment label {
- color: #555;
display: inline-block;
font-size: 1.077em;
- font-weight: bold;
padding: 0.154em 0 0;
position: relative;
}
@@ -1245,6 +1321,9 @@ a.comment-reply-link > span {
font-size: 0.8em;
color: #666;
}
+#respond .logged-in-as {
+ margin-top: 1em;
+}
#respond p {
margin: 0.769em 0 0;
}
@@ -1252,30 +1331,61 @@ a.comment-reply-link > span {
margin: 0;
}
#respond input#submit {
- background: #00a4bc;
+ background-color: #2ea2cc;
+ background-image: -moz-linear-gradient(top, #278dbc 0%, #0074a2 100%);
+ background-image: -webkit-linear-gradient(top, #278dbc 0%,#0074a2 100%);
+ background-image: -ms-linear-gradient(top, #278dbc 0%,#0074a2 100%);
+ background-image: -o-linear-gradient(top, #278dbc 0%,#0074a2 100%);
+ background-image: linear-gradient(top, #278dbc 0%,#0074a2 100%);
+
+ -moz-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
+ -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
+ -o-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
+ -ms-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
+ box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
border: none;
- border-radius: 3px;
- box-shadow: 0px 1px 2px rgba(0,0,0,0.3);
- color: #fff;
+ -moz-border-radius: 2px 0 0 0;
+ -webkit-border-radius: 2px 0 0 0;
+ -o-border-radius: 2px 0 0 0;
+ -ms-border-radius: 2px 0 0 0;
+ border-radius: 2px;
+ color: rgba( 255, 255, 255, 0.9 );
cursor: pointer;
font-size: 1em;
- font-weight: bold;
margin: 0.462em 0;
padding: 1em;
left: 30px;
- text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
+ text-shadow: 0 -1px 0 rgba(0,116,162,0.8);
}
-#respond input#submit:active {
- background: #00879c;
+#respond input#submit:hover {
color: #fff;
+ text-shadow: 0 -1px 0 rgb(0,116,162);
+
+ background-image: -moz-linear-gradient(top, #2ea2cc 0%, #0074a2 100%);
+ background-image: -webkit-linear-gradient(top, #2ea2cc 0%,#0074a2 100%);
+ background-image: -o-linear-gradient(top, #2ea2cc 0%,#0074a2 100%);
+ background-image: -ms-linear-gradient(top, #2ea2cc 0%,#0074a2 100%);
+ background-image: linear-gradient(top, #2ea2cc 0%,#0074a2 100%);
+
+ -moz-box-shadow: inset 0 1px 0 #2ea2cc, inset 0 2px 0 rgba(120,200,230,0.7);
+ -webkit-box-shadow: inset 0 1px 0 #2ea2cc, inset 0 2px 0 rgba(120,200,230,0.7);
+ -o-box-shadow: inset 0 1px 0 #2ea2cc, inset 0 2px 0 rgba(120,200,230,0.7);
+ -ms-box-shadow: inset 0 1px 0 #2ea2cc, inset 0 2px 0 rgba(120,200,230,0.7);
+ box-shadow: inset 0 1px 0 #2ea2cc, inset 0 2px 0 rgba(120,200,230,0.7);
}
-#respond #cancel-comment-reply-link {
- color: #666;
- text-decoration: none;
-}
-#respond .logged-in-as a:hover,
-#respond #cancel-comment-reply-link:hover {
- text-decoration: underline;
+#respond input#submit:active {
+ color:rgba(255,255,255,.9);
+ background-image: -moz-linear-gradient(top, #278dbc 0%, #0074a2 100%);
+ background-image: -webkit-linear-gradient(top, #278dbc 0%,#0074a2 100%);
+ background-image: -o-linear-gradient(top, #278dbc 0%,#0074a2 100%);
+ background-image: -ms-linear-gradient(top, #278dbc 0%,#0074a2 100%);
+ background-image: linear-gradient(top, #278dbc 0%,#0074a2 100%);
+
+ -moz-box-shadow: inset 0 1px 5px #005684, inset 0 -1px 0 #278dbc;
+ -webkit-box-shadow: inset 0 1px 5px #005684, inset 0 -1px 0 #278dbc;
+ -o-box-shadow: inset 0 1px 5px #005684, inset 0 -1px 0 #278dbc;
+ -ms-box-shadow: inset 0 1px 5px #005684, inset 0 -1px 0 #278dbc;
+ box-shadow: inset 0 1px 5px #005684, inset 0 -1px 0 #278dbc;
}
.commentlist #respond {
margin: 1.625em 0 0;
@@ -1285,30 +1395,23 @@ a.comment-reply-link > span {
margin: 6px 0;
}
#reply-title {
- color: #373737;
font-size: 1.5em;
- font-weight: bold;
- line-height: 0.733em;
+ line-height: 0.733;
}
.comment #reply-title {
margin-top: 1em;
}
#cancel-comment-reply-link {
- color: #888;
+ color: #bd3500;
display: block;
- font-size: 0.923em;
- font-weight: normal;
- line-height: 2.2em;
+ font-size: 0.6em;
+ font-weight: 300;
+ line-height: 2.2;
+ margin-top: 0.4em;
text-decoration: none;
- text-transform: uppercase;
-}
-#cancel-comment-reply-link:focus,
-#cancel-comment-reply-link:active,
-#cancel-comment-reply-link:hover {
- color: #ff4b33;
}
#respond label {
- line-height: 2.2em;
+ line-height: 2.2;
}
#respond input[type=text] {
display: block;
@@ -1330,7 +1433,7 @@ p.comment-form-comment {
----------------------------------------------- */
#colophon {
- background: #434343;
+ background: #f1f1f1;
clear: both;
margin-bottom: -2em;
padding-bottom: 1em;
@@ -1338,23 +1441,20 @@ p.comment-form-comment {
/* Site Generator Line */
#site-generator {
- background: #434343;
border-top: 1px solid #ddd;
- color: #fff;
font-size: 0.923em;
- line-height: 2.2em;
+ line-height: 2.2;
padding: 2.2em 0.5em;
text-align: center;
}
#site-generator a {
- color: #00a4bc;
- font-weight: bold;
+ color: #278dbc;
}
#site-generator .sep {
color: transparent;
display: inline-block;
height: 16px;
- line-height: 1.231em;
+ line-height: 1.231;
margin: 0 0.538em;
text-indent: 40px; /* Push the separator just out of the way */
width: 3.077em;
@@ -1364,6 +1464,9 @@ p.comment-form-comment {
/* =WP.com
----------------------------------------------- */
+.entry-content .twitter-tweet-rendered {
+ max-width: 100% !important; /* Override the Twitter embed fixed width */
+}
.video-player {
max-width: 100% !important;
}
@@ -1380,8 +1483,11 @@ p.comment-form-comment {
display: block;
}
#wpl-mustlogin {
-width: 240px !important;
-margin-left: -60px !important;
+ width: 240px !important;
+ margin-left: -60px !important;
+}
+img.latex {
+ display: inline;
}
/* WP.com comment form */
@@ -1415,6 +1521,35 @@ margin-left: -60px !important;
width: 99% !important;
}
+/* Infinite Scroll */
+.infinite-wrap {
+ border-top: 1px solid #ececec;
+ padding-top: 1.5em !important;
+}
+.infinite-scroll .hentry:last-of-type,
+.infinite-scroll .hentry.last-before-infinite {
+ margin-bottom: 0;
+}
+.infinite-scroll #content {
+ padding-bottom: 0.1em;
+}
+#infinite-handle span:before {
+ display: none;
+}
+#infinite-handle span {
+ background: #278dbc;
+ border-radius: 2px;
+ border: none;
+ color: #fff;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 400;
+ padding: 6px 26px;
+ text-align: center;
+}
+#infinite-handle span:hover {
+ background: #7dcae7;
+}
/* Remove margins and padding on outer containers for super-tiny screens */
@media only screen and (min-device-width: 100px) and (max-device-width: 300px) {
@@ -1427,7 +1562,8 @@ margin-left: -60px !important;
}
#page,
.widget-area,
- #main {
+ #main,
+ #branding {
width: 100%;
margin: 0;
}
diff --git a/plugins/jetpack/modules/mobile-push.php b/plugins/jetpack/modules/mobile-push.php
index 8981348b..b073348c 100644
--- a/plugins/jetpack/modules/mobile-push.php
+++ b/plugins/jetpack/modules/mobile-push.php
@@ -1,9 +1,10 @@
<?php
/**
* Module Name: Mobile Push Notifications
- * Module Description: Receive notifications on your Apple device.
+ * Module Description: Receive notifications on your mobile device.
* Sort Order: 100
* First Introduced: 1.9
+ * Requires Connection: Yes
*/
Jetpack_Sync::sync_comments( __FILE__, array(
diff --git a/plugins/jetpack/modules/module-extras.php b/plugins/jetpack/modules/module-extras.php
index 5013f7cc..22fdb924 100644
--- a/plugins/jetpack/modules/module-extras.php
+++ b/plugins/jetpack/modules/module-extras.php
@@ -56,3 +56,5 @@ add_filter( 'jetpack_can_activate_infinite-scroll', 'jetpack_can_activate_infini
require_once( dirname( __FILE__ ) . '/holiday-snow.php' );
require_once( dirname( __FILE__ ) . '/featured-content/featured-content.php' );
+
+require_once( dirname( __FILE__ ) . '/social-links.php' );
diff --git a/plugins/jetpack/modules/module-info.php b/plugins/jetpack/modules/module-info.php
index 218a9e80..cb5257f0 100644
--- a/plugins/jetpack/modules/module-info.php
+++ b/plugins/jetpack/modules/module-info.php
@@ -613,7 +613,7 @@ function jetpack_mobile_push_notifications_more_info() { ?>
<h4><?php esc_html_e( 'Mobile Push Notifications' , 'jetpack' ); ?></h4>
- <p><?php _e( 'If you have your blog added to the <a href="http://ios.wordpress.org/">WordPress for iOS app</a>, you’ll now be able to opt in to receive push notifications of new comments, which makes it easier than ever to keep up with your readers and moderate comments on the go.', 'jetpack' ); ?></p>
+ <p><?php echo sprintf( __( 'If you use <a href="%1$s">WordPress for iOS</a> or <a href="%2$s">WordPress for Android</a>, you’ll now be able to opt in to receive push notifications of new comments, which makes it easier than ever to keep up with your readers and moderate comments on the go.', 'jetpack' ), 'http://ios.wordpress.org/', 'http://android.wordpress.org/' ); ?></p>
<?php
}
@@ -776,3 +776,49 @@ function jetpack_likes_more_link() {
}
add_action( 'jetpack_learn_more_button_likes', 'jetpack_likes_more_link' );
// Likes: STOP
+
+// Debug: START
+function jetpack_debug_more_info() { ?>
+
+ <h4><?php esc_html_e( 'Debug' , 'jetpack' ); ?></h4>
+
+ <p><?php esc_html_e( "A debugging platform for the Jetpack plugin. Find out why Jetpack isn't working for you and submit a help request direct from your Dashboard.", 'jetpack' ); ?></p>
+ <?php if ( Jetpack::is_module_active( 'debug' ) ) : ?>
+ <p><a href="<?php echo admin_url( 'admin.php?page=jetpack-debugger' ); ?>"><?php esc_html_e( "Click here to start debugging.", 'jetpack' ); ?></a></p>
+
+ <?php endif; ?>
+<?php
+}
+
+function jetpack_debug_more_link() {
+ echo '<a class="button-secondary more-info-link" href="http://jetpack.me/support/debug/">' . __( 'Learn More', 'jetpack' ) . '</a>';
+}
+
+add_action( 'jetpack_module_more_info_debug', 'jetpack_debug_more_info' );
+add_action( 'jetpack_module_more_info_connected_debug', 'jetpack_debug_more_info' );
+add_action( 'jetpack_learn_more_button_debug', 'jetpack_debug_more_link' );
+// Debug: STOP
+
+// Omnisearch: START
+function jetpack_omnisearch_more_info() { ?>
+
+ <h4><?php esc_html_e( 'Omnisearch' , 'jetpack' ); ?></h4>
+
+ <p><?php esc_html_e( 'Search once, get results from everything! Currently supports searching posts, pages, comments, and plugins.', 'jetpack' ); ?></p>
+
+ <p><?php esc_html_e( 'Omnisearch plays nice with other plugins by letting other providers offer results as well.', 'jetpack' ); ?></p>
+
+ <?php if( class_exists( 'Jetpack_Omnisearch' ) && current_user_can( 'edit_posts' ) ): ?>
+ <?php echo Jetpack_Omnisearch::get_omnisearch_form(); ?>
+ <?php endif; ?>
+
+<?php
+}
+
+function jetpack_omnisearch_more_link() {
+ echo '<a class="button-secondary more-info-link" href="http://jetpack.me/support/omnisearch/">' . __( 'Learn More', 'jetpack' ) . '</a>';
+}
+
+add_action( 'jetpack_module_more_info_omnisearch', 'jetpack_omnisearch_more_info' );
+add_action( 'jetpack_learn_more_button_omnisearch', 'jetpack_omnisearch_more_link' );
+// Omnisearch: STOP
diff --git a/plugins/jetpack/modules/notes.php b/plugins/jetpack/modules/notes.php
index e33f7ff8..6022138a 100644
--- a/plugins/jetpack/modules/notes.php
+++ b/plugins/jetpack/modules/notes.php
@@ -4,6 +4,7 @@
* Module Description: Monitor and manage your site's activity with Notifications in your Toolbar and on WordPress.com.
* Sort Order: 1
* First Introduced: 1.9
+ * Requires Connection: Yes
*/
if ( !defined( 'JETPACK_NOTES__CACHE_BUSTER' ) ) define( 'JETPACK_NOTES__CACHE_BUSTER', JETPACK__VERSION . '-' . gmdate( 'oW' ) );
@@ -28,7 +29,7 @@ class Jetpack_Notifications {
* Singleton
* @static
*/
- function &init() {
+ public static function init() {
static $instance = array();
if ( !$instance ) {
@@ -42,24 +43,6 @@ class Jetpack_Notifications {
$this->jetpack = Jetpack::init();
add_action( 'init', array( &$this, 'action_init' ) );
-
- //post types that support comments
- $filt_post_types = array();
- foreach ( get_post_types() as $post_type ) {
- if ( post_type_supports( $post_type, 'comments' ) ) {
- $filt_post_types[] = $post_type;
- }
- }
-
- Jetpack_Sync::sync_posts( __FILE__, array(
- 'post_types' => $filt_post_types,
- 'post_stati' => array( 'publish' ),
- ) );
- Jetpack_Sync::sync_comments( __FILE__, array(
- 'post_types' => $filt_post_types,
- 'post_stati' => array( 'publish' ),
- 'comment_stati' => array( 'approve', 'approved', '1', 'hold', 'unapproved', 'unapprove', '0', 'spam', 'trash' ),
- ) );
}
function wpcom_static_url($file) {
@@ -104,9 +87,29 @@ class Jetpack_Notifications {
}
function action_init() {
+ //syncing must wait until after init so
+ //post types that support comments
+ $filt_post_types = array();
+ $all_post_types = get_post_types();
+ foreach ( $all_post_types as $post_type ) {
+ if ( post_type_supports( $post_type, 'comments' ) ) {
+ $filt_post_types[] = $post_type;
+ }
+ }
+
+ Jetpack_Sync::sync_posts( __FILE__, array(
+ 'post_types' => $filt_post_types,
+ 'post_stati' => array( 'publish' ),
+ ) );
+ Jetpack_Sync::sync_comments( __FILE__, array(
+ 'post_types' => $filt_post_types,
+ 'post_stati' => array( 'publish' ),
+ 'comment_stati' => array( 'approve', 'approved', '1', 'hold', 'unapproved', 'unapprove', '0', 'spam', 'trash' ),
+ ) );
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
return;
-
+
if ( !has_filter( 'show_admin_bar', '__return_true' ) && !is_user_logged_in() )
return;
@@ -119,41 +122,24 @@ class Jetpack_Notifications {
}
function styles_and_scripts() {
- wp_enqueue_style( 'notes-admin-bar-rest', $this->wpcom_static_url( '/wp-content/mu-plugins/notes/admin-bar-rest.css' ), array(), JETPACK_NOTES__CACHE_BUSTER );
+ wp_enqueue_style( 'wpcom-notes-admin-bar', $this->wpcom_static_url( '/wp-content/mu-plugins/notes/admin-bar-v2.css' ), array(), JETPACK_NOTES__CACHE_BUSTER );
wp_enqueue_style( 'noticons', $this->wpcom_static_url( '/i/noticons/noticons.css' ), array(), JETPACK_NOTES__CACHE_BUSTER );
$this->print_js();
// attempt to use core or plugin libraries if registered
- if ( wp_script_is( 'mustache', 'registered' ) ) {
- if ( !wp_script_is( 'mustache', 'queue' ) ) {
- wp_enqueue_script( 'mustache' );
- }
- }
- else {
- wp_enqueue_script( 'mustache', $this->wpcom_static_url( '/wp-content/js/mustache.js' ), null, JETPACK_NOTES__CACHE_BUSTER );
+ if ( !wp_script_is( 'mustache', 'registered' ) ) {
+ wp_register_script( 'mustache', $this->wpcom_static_url( '/wp-content/js/mustache.js' ), null, JETPACK_NOTES__CACHE_BUSTER );
}
-
- if ( wp_script_is( 'underscore', 'registered' ) ) {
- if ( !wp_script_is( 'underscore', 'queue' ) ) {
- wp_enqueue_script( 'underscore' );
- }
- }
- else {
- wp_enqueue_script( 'underscore', $this->wpcom_static_url( '/wp-content/js/underscore.js' ), null, JETPACK_NOTES__CACHE_BUSTER );
- }
- if ( wp_script_is( 'backbone', 'registered' ) ) {
- if ( !wp_script_is( 'backbone', 'queue' ) ) {
- wp_enqueue_script( 'backbone' );
- }
+ if ( !wp_script_is( 'underscore', 'registered' ) ) {
+ wp_register_script( 'underscore', $this->wpcom_static_url( '/wp-includes/js/underscore.min.js' ), null, JETPACK_NOTES__CACHE_BUSTER );
}
- else {
- wp_enqueue_script( 'backbone', $this->wpcom_static_url( '/wp-content/js/backbone.js' ), array( 'jquery', 'underscore' ), JETPACK_NOTES__CACHE_BUSTER );
+ if ( !wp_script_is( 'backbone', 'registered' ) ) {
+ wp_register_script( 'backbone', $this->wpcom_static_url( '/wp-includes/js/backbone.min.js' ), array( 'underscore' ), JETPACK_NOTES__CACHE_BUSTER );
}
- wp_enqueue_script( 'notes-postmessage', $this->wpcom_static_url( '/wp-content/js/postmessage.js' ), array(), JETPACK_NOTES__CACHE_BUSTER );
- wp_enqueue_script( 'notes-rest-common', $this->wpcom_static_url( '/wp-content/mu-plugins/notes/notes-rest-common.js' ), array( 'backbone', 'mustache', 'jquery.spin' ), JETPACK_NOTES__CACHE_BUSTER );
- wp_enqueue_script( 'notes-admin-bar-rest', $this->wpcom_static_url( '/wp-content/mu-plugins/notes/admin-bar-rest.js' ), array( 'jquery', 'underscore', 'backbone', 'jquery.spin' ), JETPACK_NOTES__CACHE_BUSTER );
+ wp_register_script( 'wpcom-notes-common', $this->wpcom_static_url( '/wp-content/mu-plugins/notes/notes-common-v2.js' ), array( 'jquery', 'underscore', 'backbone', 'mustache', 'jquery.spin' ), JETPACK_NOTES__CACHE_BUSTER );
+ wp_enqueue_script( 'wpcom-notes-admin-bar', $this->wpcom_static_url( '/wp-content/mu-plugins/notes/admin-bar-v2.js' ), array( 'wpcom-notes-common' ), JETPACK_NOTES__CACHE_BUSTER );
}
function admin_bar_menu() {
@@ -166,10 +152,10 @@ class Jetpack_Notifications {
$wp_admin_bar->add_menu( array(
'id' => 'notes',
'title' => '<span id="wpnt-notes-unread-count" class="' . esc_attr( $classes ) . '">
- <span class="noticon noticon-notification" /></span>
+ <span class="noticon noticon-notification"></span>
</span>',
'meta' => array(
- 'html' => '<div id="wpnt-notes-panel" style="display:none"><div class="wpnt-notes-panel-header"><span class="wpnt-notes-header">' . __('Notifications', 'jetpack') . '</span><span class="wpnt-notes-panel-link"></span></div></div>',
+ 'html' => '<div id="wpnt-notes-panel" style="display:none" lang="'. esc_attr( get_locale() ) . '" dir="' . ( is_rtl() ? 'rtl' : 'ltr' ) . '"><div class="wpnt-notes-panel-header"><span class="wpnt-notes-header">' . __( 'Notifications', 'jetpack' ) . '</span><span class="wpnt-notes-panel-link"></span></div></div>',
'class' => 'menupop',
),
'parent' => 'top-secondary',
diff --git a/plugins/jetpack/modules/photon.php b/plugins/jetpack/modules/photon.php
index 06db8680..23fa614f 100644
--- a/plugins/jetpack/modules/photon.php
+++ b/plugins/jetpack/modules/photon.php
@@ -4,6 +4,7 @@
* Module Description: Give your site a boost by loading images from the WordPress.com content delivery network.
* Sort Order: 15
* First Introduced: 2.0
+ * Requires Connection: Yes
*/
Jetpack_Photon::instance(); \ No newline at end of file
diff --git a/plugins/jetpack/modules/post-by-email.php b/plugins/jetpack/modules/post-by-email.php
index e8cd8873..bbc58ff2 100644
--- a/plugins/jetpack/modules/post-by-email.php
+++ b/plugins/jetpack/modules/post-by-email.php
@@ -5,6 +5,7 @@
* Module Description: Publish posts to your blog directly from your personal email account.
* First Introduced: 2.0
* Sort Order: 4
+ * Requires Connection: Yes
*/
add_action( 'jetpack_modules_loaded', array( 'Jetpack_Post_By_Email', 'init' ) );
@@ -25,7 +26,7 @@ Jetpack::enable_module_configurable( __FILE__ );
Jetpack::module_configuration_load( __FILE__, array( 'Jetpack_Post_By_Email', 'configuration_redirect' ) );
class Jetpack_Post_By_Email {
- function &init() {
+ public static function init() {
static $instance = NULL;
if ( !$instance ) {
@@ -44,7 +45,7 @@ class Jetpack_Post_By_Email {
$jetpack->sync->register( 'noop' );
}
- function configuration_redirect() {
+ static function configuration_redirect() {
wp_safe_redirect( get_edit_profile_url( get_current_user_id() ) . '#post-by-email' );
exit;
}
diff --git a/plugins/jetpack/modules/post-by-email/post-by-email.js b/plugins/jetpack/modules/post-by-email/post-by-email.js
index 7ba14bd7..0f548e72 100644
--- a/plugins/jetpack/modules/post-by-email/post-by-email.js
+++ b/plugins/jetpack/modules/post-by-email/post-by-email.js
@@ -56,7 +56,7 @@ jetpack_post_by_email = {
jQuery.post( ajaxurl, data, jetpack_post_by_email.handle_regenerated );
},
-
+
handle_regenerated: function( response ) {
var regenerated = false;
var error;
diff --git a/plugins/jetpack/modules/publicize.php b/plugins/jetpack/modules/publicize.php
index c9a37e5d..c1265cb3 100644
--- a/plugins/jetpack/modules/publicize.php
+++ b/plugins/jetpack/modules/publicize.php
@@ -4,6 +4,7 @@
* Module Description: Connect your site to popular social networks and automatically share new posts with your friends.
* Sort Order: 1
* First Introduced: 2.0
+ * Requires Connection: Yes
*/
class Jetpack_Publicize {
diff --git a/plugins/jetpack/modules/publicize/assets/publicize.css b/plugins/jetpack/modules/publicize/assets/publicize.css
index 4065cb01..64569ae9 100644
--- a/plugins/jetpack/modules/publicize/assets/publicize.css
+++ b/plugins/jetpack/modules/publicize/assets/publicize.css
@@ -3,7 +3,7 @@ div#publicize-services-block {
clear: both;
margin-bottom: 25px;
background-color: #fff;
- width: 100%;
+ padding: 25px 25px 5px 20px;
}
/* Add the logos for the Publicize services */
@@ -19,7 +19,6 @@ span.pub-logos {
span#facebook { background: url( facebook-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
span#twitter { background: url( twitter-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
-span#yahoo { background: url( yahoo-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
span#linkedin { background: url( linkedin-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
span#tumblr { background: url( tumblr-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
@@ -172,4 +171,4 @@ table#option-fb-fanpage td.details span.category {
input.fb-options {
font-family: "Lucida Grande",Verdana,Arial,sans-serif;
font-size: 12px;
-} \ No newline at end of file
+}
diff --git a/plugins/jetpack/modules/publicize/assets/publicize.js b/plugins/jetpack/modules/publicize/assets/publicize.js
index bb1f8d4c..4ae37fb7 100644
--- a/plugins/jetpack/modules/publicize/assets/publicize.js
+++ b/plugins/jetpack/modules/publicize/assets/publicize.js
@@ -72,7 +72,7 @@ jQuery( function( $ ) {
tb_remove();
window.location = 'options-general.php?page=sharing';
} );
-
+
} );
}
diff --git a/plugins/jetpack/modules/publicize/assets/rtl/publicize-rtl.css b/plugins/jetpack/modules/publicize/assets/rtl/publicize-rtl.css
index b56ab2fb..0acaa428 100644
--- a/plugins/jetpack/modules/publicize/assets/rtl/publicize-rtl.css
+++ b/plugins/jetpack/modules/publicize/assets/rtl/publicize-rtl.css
@@ -1,11 +1,11 @@
-/* This file was automatically generated on Dec 18 2012 19:58:18 */
+/* This file was automatically generated on Jun 24 2013 19:39:49 */
div#publicize-services-block {
display: inline-block;
clear: both;
margin-bottom: 25px;
background-color: #fff;
- width: 100%;
+ padding: 25px 20px 5px 25px;
}
/* Add the logos for the Publicize services */
@@ -21,7 +21,6 @@ span.pub-logos {
span#facebook { background: url( ../facebook-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
span#twitter { background: url( ../twitter-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
-span#yahoo { background: url( ../yahoo-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
span#linkedin { background: url( ../linkedin-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
span#tumblr { background: url( ../tumblr-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
@@ -174,4 +173,4 @@ table#option-fb-fanpage td.details span.category {
input.fb-options {
font-family: "Lucida Grande",Verdana,Arial,sans-serif;
font-size: 12px;
-} \ No newline at end of file
+}
diff --git a/plugins/jetpack/modules/publicize/publicize-jetpack.php b/plugins/jetpack/modules/publicize/publicize-jetpack.php
index 58e25648..454f9999 100644
--- a/plugins/jetpack/modules/publicize/publicize-jetpack.php
+++ b/plugins/jetpack/modules/publicize/publicize-jetpack.php
@@ -11,15 +11,15 @@ class Publicize extends Publicize_Base {
add_action( 'wp_ajax_publicize_facebook_options_page', array( $this, 'options_page_facebook' ) );
add_action( 'wp_ajax_publicize_twitter_options_page', array( $this, 'options_page_twitter' ) );
add_action( 'wp_ajax_publicize_linkedin_options_page', array( $this, 'options_page_linkedin' ) );
- add_action( 'wp_ajax_publicize_yahoo_options_page', array( $this, 'options_page_yahoo' ) );
add_action( 'wp_ajax_publicize_tumblr_options_save', array( $this, 'options_save_tumblr' ) );
add_action( 'wp_ajax_publicize_facebook_options_save', array( $this, 'options_save_facebook' ) );
add_action( 'wp_ajax_publicize_twitter_options_save', array( $this, 'options_save_twitter' ) );
add_action( 'wp_ajax_publicize_linkedin_options_save', array( $this, 'options_save_linkedin' ) );
- add_action( 'wp_ajax_publicize_yahoo_options_save', array( $this, 'options_save_yahoo' ) );
add_action( 'load-settings_page_sharing', array( $this, 'force_user_connection' ) );
+
+ add_filter( 'publicize_checkbox_default', array( $this, 'publicize_checkbox_default' ), 10, 4 );
add_action( 'transition_post_status', array( $this, 'save_publicized' ), 10, 3 );
}
@@ -219,7 +219,7 @@ class Publicize extends Publicize_Base {
if ( 'on' == $_REQUEST['global'] ) {
$id = $_REQUEST['connection'];
- if ( !current_user_can( Publicize::GLOBAL_CAP ) )
+ if ( !current_user_can( $this->GLOBAL_CAP ) )
return;
Jetpack::load_xml_rpc_client();
@@ -261,6 +261,17 @@ class Publicize extends Publicize_Base {
), menu_page_url( 'sharing', false ) );
}
+ function refresh_url( $service_name ) {
+ return add_query_arg( array(
+ 'action' => 'request',
+ 'service' => $service_name,
+ 'kr_nonce' => wp_create_nonce( 'keyring-request' ),
+ 'refresh' => 1,
+ 'for' => 'publicize',
+ 'nonce' => wp_create_nonce( "keyring-request-$service_name" ),
+ ), menu_page_url( 'sharing', false ) );
+ }
+
function disconnect_url( $service_name, $id ) {
return add_query_arg( array (
'action' => 'delete',
@@ -280,7 +291,6 @@ class Publicize extends Publicize_Base {
'twitter' => array(),
'linkedin' => array(),
'tumblr' => array(),
- 'yahoo' => array(),
);
if ( 'all' == $filter ) {
@@ -327,8 +337,8 @@ class Publicize extends Publicize_Base {
// Nonce check
check_admin_referer( 'options_page_facebook_' . $_REQUEST['connection'] );
- $me = $options_to_show[0];
- $pages = $options_to_show[1]['data'];
+ $me = ( ! empty( $options_to_show[0] ) ? $options_to_show[0] : false );
+ $pages = ( ! empty( $options_to_show[1]['data'] ) ? $options_to_show[1]['data'] : false );
$profile_checked = true;
$page_selected = false;
@@ -389,7 +399,6 @@ class Publicize extends Publicize_Base {
<tbody>
<?php foreach ( $pages as $i => $page ) : ?>
- <?php if ( ! isset( $page['perms'] ) ) { continue; } ?>
<?php if ( ! ( $i % 2 ) ) : ?>
<tr>
<?php endif; ?>
@@ -559,11 +568,9 @@ class Publicize extends Publicize_Base {
function options_page_twitter() { Publicize_UI::options_page_other( 'twitter' ); }
function options_page_linkedin() { Publicize_UI::options_page_other( 'linkedin' ); }
- function options_page_yahoo() { Publicize_UI::options_page_other( 'yahoo' ); }
function options_save_twitter() { $this->options_save_other( 'twitter' ); }
function options_save_linkedin() { $this->options_save_other( 'linkedin' ); }
- function options_save_yahoo() { $this->options_save_other( 'yahoo' ); }
function options_save_other( $service_name ) {
// Nonce check
@@ -571,8 +578,74 @@ class Publicize extends Publicize_Base {
$this->globalization();
}
- // stub
+ function is_expired( $expires = false ) {
+ $hour_in_seconds = 3600;
+ if ( !$expires )
+ return false; // No expires value, assume it's a permanent token
+ if ( '0000-00-00 00:00:00' == $expires )
+ return false; // Doesn't expire
+ if ( ( time() + $hour_in_seconds ) > strtotime( $expires ) )
+ return true; // Token's expiry time has passed, or will pass before $window
+ return false;
+ }
+
function refresh_tokens_message() {
+ global $post;
+ $post_id = $post ? $post->ID : 0;
+
+ $services = $this->get_services( 'all' );
+
+ // Same core nonce works for all services
+ $keyring_nonce = wp_create_nonce( 'keyring-request' );
+ $expired_tokens = false;
+
+ if ( is_array( $services ) && count( $services ) ) {
+ foreach ( $services as $name => $service ) {
+ if ( $connections = $this->get_connections( $name ) ) {
+
+ foreach ( $connections as $connection ) {
+
+ $cmeta = $this->get_connection_meta( $connection );
+
+ // If the token for this connection is expired, or expires soon, then warn
+ if ( !$this->is_expired( $cmeta['expires'] ) ) {
+ continue;
+ }
+
+ if ( !$expired_tokens ) {
+ ?>
+ <div class="error below-h2 publicize-token-refresh-message">
+ <p><?php echo esc_html( __( 'Before you hit Publish, please refresh your connection to make sure we can Publicize your post:' , 'jetpack') ); ?></p>
+ <?php
+ $expired_tokens = true;
+ }
+ // No need to request for a specific token id, since the token store detects duplication and updates a single token per service
+ $nonce = wp_create_nonce( "keyring-request-" . $name );
+ $url = $this->refresh_url( $name );
+ ?>
+ <p style="text-align: center;" id="publicize-token-refresh-<?php echo esc_attr( $name ); ?>" class="publicize-token-refresh-button">
+ <a href="<?php echo esc_url( $url ); ?>" class="button" target="_refresh_<?php echo esc_attr( $name ); ?>">
+ <?php printf( __( 'Refresh connection with %s' , 'jetpack'), Publicize::get_service_label( $name ) ); ?>
+ </a>
+ </p><?php
+ }
+ }
+ }
+ }
+ if ( $expired_tokens ) {
+ echo '</div>';
+ }
+ }
+
+ /**
+ * Already-published posts should not be Publicized by default. This filter sets checked to
+ * false if a post has already been published.
+ */
+ function publicize_checkbox_default( $checked, $post_id, $name, $connection ) {
+ if ( 'publish' == get_post_status( $post_id ) )
+ return false;
+
+ return $checked;
}
}
diff --git a/plugins/jetpack/modules/publicize/publicize.php b/plugins/jetpack/modules/publicize/publicize.php
index 16d4541c..0070e5e0 100644
--- a/plugins/jetpack/modules/publicize/publicize.php
+++ b/plugins/jetpack/modules/publicize/publicize.php
@@ -39,7 +39,7 @@ abstract class Publicize_Base {
* All users with this cap can unglobalize all other global connections, and globalize any of their own
* Globalized connections cannot be unselected by users without this capability when publishing
*/
- const GLOBAL_CAP = 'edit_others_posts';
+ var $GLOBAL_CAP = 'edit_others_posts';
/**
* Sets up the basics of Publicize
@@ -61,6 +61,7 @@ abstract class Publicize_Base {
'url',
) );
+ $this->GLOBAL_CAP = apply_filters( 'jetpack_publicize_global_connections_cap', $this->GLOBAL_CAP );
// stage 1 and 2 of 3-stage Publicize. Flag for Publicize on creation, save meta,
// then check meta and publicze based on that. stage 3 implemented on wpcom
@@ -100,8 +101,6 @@ abstract class Publicize_Base {
return 'http://' . $cmeta['connection_data']['meta']['tumblr_base_hostname'];
} elseif ( 'twitter' == $service_name ) {
return 'http://twitter.com/' . substr( $cmeta['external_display'], 1 ); // Has a leading '@'
- } else if ( 'yahoo' == $service_name ) {
- return 'http://profile.yahoo.com/' . $cmeta['external_id'];
} else if ( 'linkedin' == $service_name ) {
if ( !isset( $cmeta['connection_data']['meta']['profile_url'] ) ) {
return false;
@@ -109,11 +108,15 @@ abstract class Publicize_Base {
$profile_url_query = parse_url( $cmeta['connection_data']['meta']['profile_url'], PHP_URL_QUERY );
wp_parse_str( $profile_url_query, $profile_url_query_args );
- if ( !isset( $profile_url_query_args['key'] ) ) {
+ if ( isset( $profile_url_query_args['key'] ) ) {
+ $id = $profile_url_query_args['key'];
+ } elseif ( isset( $profile_url_query_args['id'] ) ) {
+ $id = $profile_url_query_args['id'];
+ } else {
return false;
}
- return esc_url_raw( add_query_arg( 'id', urlencode( $profile_url_query_args['key'] ), 'http://www.linkedin.com/profile/view' ) );
+ return esc_url_raw( add_query_arg( 'id', urlencode( $id ), 'http://www.linkedin.com/profile/view' ) );
} else {
return false; // no fallback. we just won't link it
}
@@ -139,11 +142,8 @@ abstract class Publicize_Base {
}
}
- function get_service_label( $service_name ) {
+ public static function get_service_label( $service_name ) {
switch ( $service_name ) {
- case 'yahoo':
- return 'Yahoo!';
- break;
case 'linkedin':
return 'LinkedIn';
break;
@@ -211,8 +211,7 @@ abstract class Publicize_Base {
$cron_user = null;
$submit_post = true;
- // don't do anything if its not actually a post
- if ( 'post' !== $post->post_type )
+ if ( ! $this->post_type_is_publicizeable( $post->post_type ) )
return;
// Don't Publicize during certain contexts:
@@ -285,7 +284,13 @@ abstract class Publicize_Base {
*/
foreach ( (array) $this->get_services( 'connected' ) as $service_name => $connections ) {
foreach ( $connections as $connection ) {
- if ( false == apply_filters( 'wpas_submit_post?', $submit_post, $post_id, $service_name ) ) {
+ $connection_data = '';
+ if ( method_exists( $connection, 'get_meta' ) )
+ $connection_data = $connection->get_meta( 'connection_data' );
+ elseif ( ! empty( $connection['connection_data'] ) )
+ $connection_data = $connection['connection_data'];
+
+ if ( false == apply_filters( 'wpas_submit_post?', $submit_post, $post_id, $service_name, $connection_data ) ) {
delete_post_meta( $post_id, $this->PENDING );
continue;
}
@@ -325,4 +330,20 @@ abstract class Publicize_Base {
// Next up will be ::publicize_post()
}
+
+ /**
+ * Is a given post type Publicize-able?
+ *
+ * Not every CPT lends itself to Publicize-ation. Allow CPTs to register by adding their CPT via
+ * the publicize_post_types array filter.
+ *
+ * @param string $post_type The post type to check.
+ * $return bool True if the post type can be Publicized.
+ */
+ function post_type_is_publicizeable( $post_type ) {
+ if ( 'post' == $post_type )
+ return true;
+
+ return post_type_supports( $post_type, 'publicize' );
+ }
}
diff --git a/plugins/jetpack/modules/publicize/ui.php b/plugins/jetpack/modules/publicize/ui.php
index d9d2b37c..06d0d435 100644
--- a/plugins/jetpack/modules/publicize/ui.php
+++ b/plugins/jetpack/modules/publicize/ui.php
@@ -71,7 +71,7 @@ class Publicize_UI {
add_thickbox();
}
- function connected_notice( $service_name ) { ?>
+ public static function connected_notice( $service_name ) { ?>
<div class='updated'>
<p><?php printf( __( 'You have successfully connected your blog with your %s account.', 'jetpack' ), Publicize::get_service_label( $service_name ) ); ?></p>
</div><?php
@@ -91,14 +91,14 @@ class Publicize_UI {
<?php esc_html_e( 'Connect your blog to popular social networking sites and automatically share new posts with your friends.', 'jetpack' ) ?>
<?php esc_html_e( 'You can make a connection for just yourself or for all users on your blog. Shared connections are marked with the (Shared) text.', 'jetpack' ); ?>
</p>
-
+
<?php
if ( $this->in_jetpack )
$doc_link = "http://jetpack.me/support/publicize/";
else
$doc_link = "http://en.support.wordpress.com/publicize/";
?>
-
+
<p>&rarr; <a href="<?php echo esc_url( $doc_link ); ?>"><?php esc_html_e( 'More information on using Publicize.', 'jetpack' ); ?></a></p>
<div id="publicize-services-block">
@@ -152,7 +152,7 @@ class Publicize_UI {
<?php if ( 0 == $cmeta['connection_data']['user_id'] ) : ?>
<small>(<?php esc_html_e( 'Shared', 'jetpack' ); ?>)</small>
- <?php if ( current_user_can( Publicize::GLOBAL_CAP ) ) : ?>
+ <?php if ( current_user_can( $this->publicize->GLOBAL_CAP ) ) : ?>
<a class="pub-disconnect-button" title="<?php esc_html_e( 'Disconnect', 'jetpack' ); ?>" href="<?php echo esc_url( $disconnect_url ); ?>">×</a>
<?php endif; ?>
@@ -170,6 +170,18 @@ class Publicize_UI {
</div>
</div>
<?php endforeach; ?>
+ <script>
+ (function($){
+ $('.pub-disconnect-button').on('click', function(e){
+ if ( confirm( '<?php echo esc_js( __( 'Are you sure you want to stop Publicizing posts to this connection?', 'jetpack' ) ); ?>' ) ) {
+ return true;
+ } else {
+ e.preventDefault();
+ return false;
+ }
+ })
+ })(jQuery);
+ </script>
</div>
<?php wp_nonce_field( "wpas_posts_{$_blog_id}", "_wpas_posts_{$_blog_id}_nonce" ); ?>
@@ -178,8 +190,9 @@ class Publicize_UI {
}
- function global_checkbox( $service_name, $id ) {
- if ( current_user_can( Publicize::GLOBAL_CAP ) ) : ?>
+ public static function global_checkbox( $service_name, $id ) {
+ global $publicize;
+ if ( current_user_can( $publicize->GLOBAL_CAP ) ) : ?>
<p>
<input id="globalize_<?php echo $service_name; ?>" type="checkbox" name="global" value="<?php echo wp_create_nonce( 'publicize-globalize-' . $id ) ?>" />
<label for="globalize_<?php echo $service_name; ?>"><?php _e( 'Make this connection available to all users of this blog?', 'jetpack' ); ?></label>
@@ -195,7 +208,7 @@ class Publicize_UI {
</div><?php
}
- function options_page_other( $service_name ) {
+ public static function options_page_other( $service_name ) {
// Nonce check
check_admin_referer( "options_page_{$service_name}_" . $_REQUEST['connection'] );
?>
@@ -363,7 +376,7 @@ jQuery( function($) {
function post_page_metabox() {
global $post;
- if ( 'post' != $post->post_type )
+ if ( ! $this->publicize->post_type_is_publicizeable( $post->post_type ) )
return;
$user_id = empty( $post->post_author ) ? $GLOBALS['user_ID'] : $post->post_author;
@@ -400,7 +413,13 @@ jQuery( function($) {
foreach ( $services as $name => $connections ) {
foreach ( $connections as $connection ) {
- if ( !$continue = apply_filters( 'wpas_submit_post?', true, $post->ID, $name ) )
+ $connection_data = '';
+ if ( method_exists( $connection, 'get_meta' ) )
+ $connection_data = $connection->get_meta( 'connection_data' );
+ elseif ( ! empty( $connection['connection_data'] ) )
+ $connection_data = $connection['connection_data'];
+
+ if ( !$continue = apply_filters( 'wpas_submit_post?', true, $post->ID, $name, $connection_data ) )
continue;
if ( !empty( $connection->unique_id ) )
@@ -436,7 +455,7 @@ jQuery( function($) {
// those connections, don't let them change it
$cmeta = $this->publicize->get_connection_meta( $connection );
$hidden_checkbox = false;
- if ( !$done && ( 0 == $cmeta['connection_data']['user_id'] && !current_user_can( Publicize::GLOBAL_CAP ) ) ) {
+ if ( !$done && ( 0 == $cmeta['connection_data']['user_id'] && !current_user_can( $this->publicize->GLOBAL_CAP ) ) ) {
$disabled = ' disabled="disabled"';
$hidden_checkbox = true;
}
diff --git a/plugins/jetpack/modules/sharedaddy.php b/plugins/jetpack/modules/sharedaddy.php
index f6f4ad6e..924176fa 100644
--- a/plugins/jetpack/modules/sharedaddy.php
+++ b/plugins/jetpack/modules/sharedaddy.php
@@ -1,10 +1,11 @@
-<?php
+<?php
/**
* Module Name: Sharing
* Module Description: The most super duper sharing tool on the interwebs. Share content with Facebook, Twitter, and many more.
* Sort Order: 5
* First Introduced: 1.1
* Major Changes In: 1.2
+ * Requires Connection: No
*/
if ( !function_exists( 'sharing_init' ) )
diff --git a/plugins/jetpack/modules/sharedaddy/admin-sharing.css b/plugins/jetpack/modules/sharedaddy/admin-sharing.css
index aea30792..51234530 100644
--- a/plugins/jetpack/modules/sharedaddy/admin-sharing.css
+++ b/plugins/jetpack/modules/sharedaddy/admin-sharing.css
@@ -6,7 +6,7 @@
-webkit-border-radius: 6px;
margin-top:15px;
min-width: 700px;
- width: 100%;
+ width: 100%;
float: left;
margin-bottom: 25px;
}
@@ -34,7 +34,7 @@
}
.description{
- width: 180px;
+ width: 180px;
vertical-align: top;
}
@@ -90,7 +90,9 @@
.services ul li#linkedin, #available-services .preview-linkedin div.option-smart-off{background: #FFF url(images/linkedin.png) no-repeat 4px 5px;}
.services ul li#tumblr,#available-services .preview-tumblr{background: #FFF url(images/tumblr.png) no-repeat 4px 5px; padding-right: 10px;}
.services ul li#google-plus-1,#available-services .preview-google-plus-1{background: #FFF url(images/googleplus1.png) no-repeat 4px 5px; padding-right: 10px;}
-.services ul li#pinterest,#available-services .preview-pinterest{background: #FFF url(images/pinterest.png) no-repeat 4px 5px; padding-right: 10px;}
+.services ul li#pinterest,#available-services .preview-pinterest{background: #FFF url(images/pinterest.png) no-repeat 5px 6px; padding-right: 10px;}
+.services ul li#pocket,#available-services .preview-pocket{background: #FFF url(images/pocket.png) no-repeat 4px 5px; padding-right: 10px;}
+.services ul li#kindle,#available-services .preview-kindle{background: #FFF url(images/kindle.png) no-repeat 4px 5px; padding-right: 10px;}
.services ul li.share-custom, #available-services .preview-custom{background: #FFF url(images/custom.png) no-repeat 4px 5px; no-repeat 4px 5px; padding-right: 10px;}
@@ -181,6 +183,20 @@
height: 20px;
}
+.preview-pinterest .option-smart-on {
+ background: #FFF url(images/smart-pinterest.png) no-repeat top left;
+ background-size: 58px 20px;
+ width: 58px;
+ height: 20px;
+}
+
+.preview-pocket .option-smart-on {
+ background: #FFF url(images/smart-pocket.png) no-repeat top left;
+ background-size: 60px 20px;
+ width: 60px;
+ height: 20px;
+}
+
.services .preview li.share-custom {
border-radius: 6px;
-moz-border-radius: 6px;
@@ -222,7 +238,7 @@
#live-preview h2{
font-size:20px;
font-weight: normal !important;
- color: #e3e3e3;
+ color: #e3e3e3;
}
#live-preview{
@@ -230,17 +246,17 @@
border-bottom-left-radius:6px 6px;
border-bottom-right-radius:6px 6px;
-moz-border-radius-bottomleft: 6px;
- -moz-border-radius-bottomright: 6px;
+ -moz-border-radius-bottomright: 6px;
}
.clearing{
clear: both;
}
-
+
.options .options-left{
float: left;
}
-
+
.input label{
font-size: 11px;
line-height: 16px;
@@ -253,20 +269,20 @@
border-top: 1px #e3e3e3 solid;
margin-top:4px;
}
-
+
.utility{
float: right;
padding-top:10px;
padding-right: 10px;
font-size: 10px;
}
-
+
.advanced input[type=submit]{
float: left;
margin-top:10px;
margin-right: 10px;
}
-
+
.services li.dropzone {
border: 1px dashed #999;
background: #e3e3e3;
@@ -297,7 +313,7 @@
#hidden-drop-target p {
font-size: 10px;
margin: 0 0 10px 0;
-
+
}
.sharing-hidden .inner {
@@ -370,6 +386,8 @@
.services ul li#tumblr,#available-services .preview-tumblr{background: #FFF url(images/tumblr@2x.png) no-repeat 4px 5px; padding-right: 10px;}
.services ul li#google-plus-1,#available-services .preview-google-plus-1{background: #FFF url(images/googleplus1@2x.png) no-repeat 4px 5px; padding-right: 10px;}
.services ul li#pinterest,#available-services .preview-pinterest{background: #FFF url(images/pinterest@2x.png) no-repeat 4px 5px; padding-right: 10px;}
+ .services ul li#pocket,#available-services .preview-pocket{background: #FFF url(images/pocket@2x.png) no-repeat 4px 5px; padding-right: 10px;}
+ .services ul li#kindle,#available-services .preview-kindle{background: #FFF url(images/kindle@2x.png) no-repeat 4px 5px; padding-right: 10px;}
.services ul li.share-custom, #available-services .preview-custom{background: #FFF url(images/custom@2x.png) no-repeat 4px 5px; no-repeat 4px 5px; padding-right: 10px;}
.services ul li#facebook, #available-services .preview-facebook div.option-smart-off,
@@ -385,6 +403,8 @@
.services ul li#tumblr,#available-services .preview-tumblr,
.services ul li#google-plus-1,#available-services .preview-google-plus-1,
.services ul li#pinterest,#available-services .preview-pinterest,
+ .services ul li#pocket,#available-services .preview-pocket,
+ .services ul li#kindle,#available-services .preview-kindle,
.services ul li.share-custom, #available-services .preview-custom{
background-size: 16px 16px;
}
@@ -425,4 +445,8 @@
background-image: url(images/smart-pinterest@2x.png);
}
+ .preview-pocket .option-smart-on {
+ background-image: url(images/smart-pocket@2x.png);
+ }
+
} \ No newline at end of file
diff --git a/plugins/jetpack/modules/sharedaddy/admin-sharing.js b/plugins/jetpack/modules/sharedaddy/admin-sharing.js
index a11d469f..b396ef60 100644
--- a/plugins/jetpack/modules/sharedaddy/admin-sharing.js
+++ b/plugins/jetpack/modules/sharedaddy/admin-sharing.js
@@ -5,7 +5,7 @@
if ( $( this ).data( 'hasappeared' ) !== true ) {
var item = $( '.sharing-hidden .inner' );
var original = $( this ).parents( 'li' );
-
+
// Create a timer to make the area appear if the mouse hovers for a period
var timer = setTimeout( function() {
$( item ).css( {
@@ -14,47 +14,47 @@
} ).slideDown( 200, function() {
// Mark the item as have being appeared by the hover
$( original ).data( 'hasappeared', true ).data( 'hasoriginal', true ).data( 'hasitem', false );
-
+
// Remove all special handlers
$( item ).mouseleave( handler_item_leave ).mouseenter( handler_item_enter );
$( original ).mouseleave( handler_original_leave ).mouseenter( handler_original_enter );
-
+
// Add a special handler to quickly close the item
$( original ).click( close_it );
} );
-
+
// The following handlers take care of the mouseenter/mouseleave for the share button and the share area - if both are left then we close the share area
var handler_item_leave = function() {
$( original ).data( 'hasitem', false );
-
+
if ( $( original ).data( 'hasoriginal' ) === false ) {
var timer = setTimeout( close_it, 800 );
$( original ).data( 'timer2', timer );
}
};
-
+
var handler_item_enter = function() {
$( original ).data( 'hasitem', true );
clearTimeout( $( original ).data( 'timer2' ) );
- }
-
+ }
+
var handler_original_leave = function() {
$( original ).data( 'hasoriginal', false );
-
+
if ( $( original ).data( 'hasitem' ) === false ) {
var timer = setTimeout( close_it, 800 );
$( original ).data( 'timer2', timer );
}
};
-
+
var handler_original_enter = function() {
$( original ).data( 'hasoriginal', true );
clearTimeout( $( original ).data( 'timer2' ) );
};
-
+
var close_it = function() {
item.slideUp( 200 );
-
+
// Clear all hooks
$( original ).unbind( 'mouseleave', handler_original_leave ).unbind( 'mouseenter', handler_original_enter );
$( item ).unbind( 'mouseleave', handler_item_leave ).unbind( 'mouseenter', handler_item_leave );
@@ -63,7 +63,7 @@
return false;
};
}, 200 );
-
+
// Remember the timer so we can detect it on the mouseout
$( this ).data( 'timer', timer );
}
@@ -73,14 +73,14 @@
$( this ).data( 'timer', false );
} );
}
-
+
function update_preview() {
var item;
var button_style = $( '#button_style' ).val();
-
+
// Clear the live preview
$( '#live-preview ul.preview li' ).remove();
-
+
// Add label
if ( $( '#save-enabled-shares input[name=visible]' ).val() != '' || $( '#save-enabled-shares input[name=hidden]' ).val() != '' )
$( '#live-preview ul.preview' ).append( $( '#live-preview ul.archive .sharing-label' ).clone() );
@@ -92,14 +92,14 @@
$( '#live-preview ul.preview' ).append( $( '#live-preview ul.archive li.preview-' + service ).clone() );
}
} );
-
+
// Add any hidden items
if ( $( '#save-enabled-shares input[name=hidden]' ).val() != '' ) {
// Add share button
$( '#live-preview ul.preview' ).append( $( '#live-preview ul.archive .share-more' ).parent().clone() );
-
+
$( '.sharing-hidden ul li' ).remove();
-
+
// Add hidden items into the inner panel
$( 'ul.services-hidden li' ).each( function( pos, item ) {
if ( $( this ).hasClass( 'service' ) ) {
@@ -107,10 +107,10 @@
$( '.sharing-hidden .inner ul' ).append( $( '#live-preview ul.archive .preview-' + service ).clone() );
}
} );
-
+
enable_share_button();
}
-
+
$( '#live-preview div.sharedaddy' ).removeClass( 'sd-social-icon' );
$( '#live-preview li.advanced' ).removeClass( 'no-icon' );
@@ -126,8 +126,8 @@
} );
} else if ( 'text' == button_style ) {
$( '#live-preview li.advanced' ).addClass( 'no-icon' );
- }
-
+ }
+
}
function sharing_option_changed() {
@@ -135,25 +135,25 @@
// Loading icon
$( this ).parents( 'li:first' ).css( 'backgroundImage', 'url("' + sharing_loading_icon + '")' );
-
+
// Save
$( this ).parents( 'form' ).ajaxSubmit( function( response ) {
if ( response.indexOf( '<!---' ) >= 0 ) {
var button = response.substring( 0, response.indexOf( '<!--->' ) );
var preview = response.substring( response.indexOf( '<!--->' ) + 6 );
-
+
if ( $( item ).is( ':submit' ) === true ) {
// Update the DOM using a bit of cut/paste technology
-
+
$( item ).parents( 'li:first' ).replaceWith( button );
}
$( '#live-preview ul.archive li.preview-' + $( item ).parents( 'form' ).find( 'input[name=service]' ).val() ).replaceWith( preview );
}
-
+
// Update preview
update_preview();
-
+
// Restore the icon
$( item ).parents( 'li:first' ).removeAttr( 'style' );
} );
@@ -163,9 +163,17 @@
return true;
}
+ function showExtraOptions( service ) {
+ jQuery( '.' + service + '-extra-options' ).css( { backgroundColor: '#ffffcc' } ).fadeIn();
+ }
+
+ function hideExtraOptions( service ) {
+ jQuery( '.' + service + '-extra-options' ).fadeOut( 'slow' );
+ }
+
function save_services() {
$( '#enabled-services h3 img' ).show();
-
+
// Toggle various dividers/help texts
if ( $( '#enabled-services ul.services-enabled li.service' ).length > 0 ) {
$( '#drag-instructions' ).hide();
@@ -173,21 +181,28 @@
else {
$( '#drag-instructions' ).show();
}
-
+
if ( $( '#enabled-services li.service' ).length > 0 ) {
$( '#live-preview .services h2' ).hide();
}
else {
$( '#live-preview .services h2' ).show();
}
-
+
// Gather the modules
var visible = [], hidden = [];
-
+
$( 'ul.services-enabled li' ).each( function() {
if ( $( this ).hasClass( 'service' ) ) {
// Ready for saving
visible[visible.length] = $( this ).attr( 'id' );
+ showExtraOptions( $( this ).attr( 'id' ) );
+ }
+ } );
+
+ $( 'ul.services-available li' ).each( function() {
+ if ( $( this ).hasClass( 'service' ) ) {
+ hideExtraOptions( $( this ).attr( 'id' ) );
}
} );
@@ -195,15 +210,16 @@
if ( $( this ).hasClass( 'service' ) ) {
// Ready for saving
hidden[hidden.length] = $( this ).attr( 'id' );
+ showExtraOptions( $( this ).attr( 'id' ) );
}
} );
// Set the hidden element values
$( '#save-enabled-shares input[name=visible]' ).val( visible.join( ',' ) );
$( '#save-enabled-shares input[name=hidden]' ).val( hidden.join( ',' ) );
-
+
update_preview();
-
+
// Save it
$( '#save-enabled-shares' ).ajaxSubmit( function() {
$( '#enabled-services h3 img' ).hide();
@@ -234,7 +250,7 @@
},
helper: function( event, ui ) {
ui.find( '.advanced-form' ).hide();
-
+
return ui.clone();
},
start: function( event, ui ) {
@@ -262,13 +278,13 @@
$( '.advanced-form' ).hide();
}
} );
-
+
// Live preview 'hidden' button
$( '.preview-hidden a' ).click( function() {
$( this ).parent().find( '.preview' ).toggle();
return false;
} );
-
+
// Add service
$( '#new-service form' ).ajaxForm( {
beforeSubmit: function() {
@@ -278,7 +294,7 @@
},
success: function( response ) {
$( '#new-service-form img' ).hide();
-
+
if ( response == '1' ) {
$( '#new-service-form .inerror' ).removeClass( 'inerror' ).addClass( 'error' );
$( '#new-service-form .error' ).show();
@@ -290,38 +306,38 @@
}
}
);
-
+
function init_handlers() {
$( '#services-config a.remove' ).unbind( 'click' ).click( function() {
var form = $( this ).parent().next();
-
+
// Loading icon
$( this ).parents( 'li:first' ).css( 'backgroundImage', 'url("' + sharing_loading_icon + '")' );
-
+
// Save
form.ajaxSubmit( function( response ) {
// Remove the item
form.parents( 'li:first' ).fadeOut( function() {
$( this ).remove();
-
+
// Update preview
update_preview();
} );
} );
-
+
return false;
} );
}
-
+
$( '#button_style' ).change( function() {
update_preview();
return true;
} ).change();
-
+
$( 'input[name=sharing_label]' ).blur( function() {
$('#live-preview h3.sd-title').html( $( '<div/>' ).text( $( this ).val() ).html() );
} );
-
+
init_handlers();
enable_share_button();
} );
diff --git a/plugins/jetpack/modules/sharedaddy/images/facebook.png b/plugins/jetpack/modules/sharedaddy/images/facebook.png
index 8850a80b..91d3702f 100644
--- a/plugins/jetpack/modules/sharedaddy/images/facebook.png
+++ b/plugins/jetpack/modules/sharedaddy/images/facebook.png
Binary files differ
diff --git a/plugins/jetpack/modules/sharedaddy/images/facebook@2x.png b/plugins/jetpack/modules/sharedaddy/images/facebook@2x.png
index a88a52f6..10b36803 100644
--- a/plugins/jetpack/modules/sharedaddy/images/facebook@2x.png
+++ b/plugins/jetpack/modules/sharedaddy/images/facebook@2x.png
Binary files differ
diff --git a/plugins/jetpack/modules/sharedaddy/images/googleplus1.png b/plugins/jetpack/modules/sharedaddy/images/googleplus1.png
index 5f0a05e5..ee687af1 100644
--- a/plugins/jetpack/modules/sharedaddy/images/googleplus1.png
+++ b/plugins/jetpack/modules/sharedaddy/images/googleplus1.png
Binary files differ
diff --git a/plugins/jetpack/modules/sharedaddy/images/googleplus1@2x.png b/plugins/jetpack/modules/sharedaddy/images/googleplus1@2x.png
index 26054392..60dd1c03 100644
--- a/plugins/jetpack/modules/sharedaddy/images/googleplus1@2x.png
+++ b/plugins/jetpack/modules/sharedaddy/images/googleplus1@2x.png
Binary files differ
diff --git a/plugins/jetpack/modules/sharedaddy/images/icon-facebook-2x.png b/plugins/jetpack/modules/sharedaddy/images/icon-facebook-2x.png
index a5c71943..10b36803 100644
--- a/plugins/jetpack/modules/sharedaddy/images/icon-facebook-2x.png
+++ b/plugins/jetpack/modules/sharedaddy/images/icon-facebook-2x.png
Binary files differ
diff --git a/plugins/jetpack/modules/sharedaddy/images/icon-facebook.png b/plugins/jetpack/modules/sharedaddy/images/icon-facebook.png
index de6a8a14..91d3702f 100644
--- a/plugins/jetpack/modules/sharedaddy/images/icon-facebook.png
+++ b/plugins/jetpack/modules/sharedaddy/images/icon-facebook.png
Binary files differ
diff --git a/plugins/jetpack/modules/sharedaddy/recaptchalib.php b/plugins/jetpack/modules/sharedaddy/recaptchalib.php
index a9716772..205a4a2d 100644
--- a/plugins/jetpack/modules/sharedaddy/recaptchalib.php
+++ b/plugins/jetpack/modules/sharedaddy/recaptchalib.php
@@ -108,7 +108,7 @@ function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
if ($pubkey == null || $pubkey == '') {
die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
}
-
+
if ($use_ssl) {
$server = RECAPTCHA_API_SECURE_SERVER;
} else {
@@ -159,8 +159,8 @@ function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $ex
die ("For security reasons, you must pass the remote ip to reCAPTCHA");
}
-
-
+
+
//discard spam submissions
if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
$recaptcha_response = new ReCaptchaResponse();
@@ -215,7 +215,7 @@ function _recaptcha_aes_encrypt($val,$ky) {
if (! function_exists ("mcrypt_encrypt")) {
die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
}
- $mode=MCRYPT_MODE_CBC;
+ $mode=MCRYPT_MODE_CBC;
$enc=MCRYPT_RIJNDAEL_128;
$val=_recaptcha_aes_pad($val);
return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
@@ -232,11 +232,11 @@ function recaptcha_mailhide_url($pubkey, $privkey, $email) {
die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
"you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>");
}
-
+
$ky = pack('H*', $privkey);
$cryptmail = _recaptcha_aes_encrypt ($email, $ky);
-
+
return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
}
@@ -267,7 +267,7 @@ function _recaptcha_mailhide_email_parts ($email) {
function recaptcha_mailhide_html($pubkey, $privkey, $email) {
$emailparts = _recaptcha_mailhide_email_parts ($email);
$url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
-
+
return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
"' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);
diff --git a/plugins/jetpack/modules/sharedaddy/sharedaddy.php b/plugins/jetpack/modules/sharedaddy/sharedaddy.php
index ab8085ca..cefecf75 100644
--- a/plugins/jetpack/modules/sharedaddy/sharedaddy.php
+++ b/plugins/jetpack/modules/sharedaddy/sharedaddy.php
@@ -59,14 +59,14 @@ function sharing_meta_box_save( $post_id ) {
}
}
}
-
+
return $post_id;
}
function sharing_meta_box_protected( $protected, $meta_key, $meta_type ) {
if ( 'sharing_disabled' == $meta_key )
$protected = true;
-
+
return $protected;
}
@@ -83,7 +83,7 @@ function sharing_add_plugin_settings($links, $file) {
$links[] = '<a href="options-general.php?page=sharing.php">' . __( 'Settings', 'jetpack' ) . '</a>';
$links[] = '<a href="http://support.wordpress.com/sharing/">' . __( 'Support', 'jetpack' ) . '</a>';
}
-
+
return $links;
}
diff --git a/plugins/jetpack/modules/sharedaddy/sharing-service.php b/plugins/jetpack/modules/sharedaddy/sharing-service.php
index c8efee33..8b10b6e0 100644
--- a/plugins/jetpack/modules/sharedaddy/sharing-service.php
+++ b/plugins/jetpack/modules/sharedaddy/sharing-service.php
@@ -54,6 +54,7 @@ class Sharing_Service {
'google-plus-1' => 'Share_GooglePlus1',
'tumblr' => 'Share_Tumblr',
'pinterest' => 'Share_Pinterest',
+ 'pocket' => 'Share_Pocket',
);
// Add any custom services in
@@ -416,7 +417,9 @@ function sharing_add_footer() {
endif;
endif;
- wp_print_scripts( 'sharing-js' );
+ wp_enqueue_script( 'sharing-js' );
+ $recaptcha__options = array( 'lang' => get_base_recaptcha_lang_code() );
+ wp_localize_script('sharing-js', 'recaptcha_options', $recaptcha__options);
}
$sharer = new Sharing_Service();
@@ -452,9 +455,9 @@ function sharing_process_requests() {
}
}
}
-add_action( 'template_redirect', 'sharing_process_requests' );
+add_action( 'template_redirect', 'sharing_process_requests', 9 );
-function sharing_display( $text = '' ) {
+function sharing_display( $text = '', $echo = false ) {
global $post, $wp_current_filter;
if ( is_preview() ) {
@@ -518,7 +521,7 @@ function sharing_display( $text = '' ) {
$sharing_content = '';
if ( $show ) {
- $enabled = $sharer->get_blog_services();
+ $enabled = apply_filters( 'sharing_enabled', $sharer->get_blog_services() );
if ( count( $enabled['all'] ) > 0 ) {
global $post;
@@ -584,7 +587,7 @@ function sharing_display( $text = '' ) {
$sharing_content .= '<li class="share-end"></li></ul></div></div>';
}
- $sharing_content .= '<div class="sharing-clear"></div></div></div></div>';
+ $sharing_content .= '</div></div></div>';
// Register our JS
wp_register_script( 'sharing-js', plugin_dir_url( __FILE__ ).'sharing.js', array( 'jquery' ), '20121205' );
@@ -592,8 +595,35 @@ function sharing_display( $text = '' ) {
}
}
- return $text.$sharing_content;
+ if ( $echo )
+ echo $text.$sharing_content;
+ else
+ return $text.$sharing_content;
}
add_filter( 'the_content', 'sharing_display', 19 );
add_filter( 'the_excerpt', 'sharing_display', 19 );
+function get_base_recaptcha_lang_code() {
+
+ $base_recaptcha_lang_code_mapping = array(
+ 'en' => 'en',
+ 'nl' => 'nl',
+ 'fr' => 'fr',
+ 'fr-be' => 'fr',
+ 'fr-ca' => 'fr',
+ 'fr-ch' => 'fr',
+ 'de' => 'de',
+ 'pt' => 'pt',
+ 'pt-br' => 'pt',
+ 'ru' => 'ru',
+ 'es' => 'es',
+ 'tr' => 'tr'
+ );
+
+ $blog_lang_code = function_exists( 'get_blog_lang_code' ) ? get_blog_lang_code() : get_bloginfo( 'language' );
+ if( isset( $base_recaptcha_lang_code_mapping[ $blog_lang_code ] ) )
+ return $base_recaptcha_lang_code_mapping[ $blog_lang_code ];
+
+ // if no base mapping is found return default 'en'
+ return 'en';
+}
diff --git a/plugins/jetpack/modules/sharedaddy/sharing-sources.php b/plugins/jetpack/modules/sharedaddy/sharing-sources.php
index 256513cb..53164741 100644
--- a/plugins/jetpack/modules/sharedaddy/sharing-sources.php
+++ b/plugins/jetpack/modules/sharedaddy/sharing-sources.php
@@ -197,7 +197,7 @@ class Share_Email extends Sharing_Source {
}
public function get_name() {
- return __( 'Email', 'jetpack' );
+ return _x( 'Email', 'as sharing source', 'jetpack' );
}
// Default does nothing
@@ -317,6 +317,9 @@ class Share_Email extends Sharing_Source {
class Share_Twitter extends Sharing_Source {
var $shortname = 'twitter';
+ // 'https://dev.twitter.com/docs/api/1.1/get/help/configuration' ( 2013/06/24 ) short_url_length is 22
+ var $short_url_length = 24;
+
public function __construct( $id, array $settings ) {
parent::__construct( $id, $settings );
@@ -402,8 +405,8 @@ class Share_Twitter extends Sharing_Source {
$sig = '';
}
- $suffix_length = $strlen( " {$post_link}{$sig}" );
+ $suffix_length = $this->short_url_length + $strlen( " {$sig}" );
// $sig is handled by twitter in their 'via' argument.
// $post_link is handled by twitter in their 'url' argument.
if ( 140 < $strlen( $post_title ) + $suffix_length ) {
@@ -600,28 +603,14 @@ class Share_LinkedIn extends Sharing_Source {
public function process_request( $post, array $post_data ) {
- setup_postdata( $post );
-
$post_link = $this->get_share_url( $post->ID );
- // http://www.linkedin.com/shareArticle?mini=true&url={articleUrl}&title={articleTitle}&summary={articleSummary}&source={articleSource}
-
- $encoded_title = rawurlencode( $post->post_title );
- if( strlen( $encoded_title ) > 200 )
- $encoded_title = substr( $encoded_title, 0, 197 ) . '...';
-
- $encoded_summary = rawurlencode( strip_tags( get_the_excerpt() ) );
- if( strlen( $encoded_summary ) > 256 )
- $encoded_summary = substr( $encoded_summary, 0, 253 ) . '...';
-
- $source = get_bloginfo( 'name' );
+ // Using the same URL as the official button, which is *not* LinkedIn's documented sharing link
+ // http://www.linkedin.com/cws/share?url={url}&token=&isFramed=false
$linkedin_url = add_query_arg( array(
- 'title' => $encoded_title,
'url' => rawurlencode( $post_link ),
- 'source' => rawurlencode( $source ),
- 'summary' => $encoded_summary,
- ), 'http://www.linkedin.com/shareArticle?mini=true' );
+ ), 'http://www.linkedin.com/cws/share?token=&isFramed=false' );
// Record stats
parent::process_request( $post, $post_data );
@@ -1214,6 +1203,8 @@ class Share_Pinterest extends Sharing_Source {
s.src = window.location.protocol + "//assets.pinterest.com/js/pinit.js";
var x = document.getElementsByTagName("script")[0];
x.parentNode.insertBefore(s, x);
+ // if 'Pin it' button has 'counts' make container wider
+ jQuery(window).load( function(){ jQuery( 'li.share-pinterest a span:visible' ).closest( '.share-pinterest' ).width( '80px' ); } );
</script>
<?php else : ?>
<script type="text/javascript">
@@ -1240,3 +1231,65 @@ class Share_Pinterest extends Sharing_Source {
<?php endif;
}
}
+
+class Share_Pocket extends Sharing_Source {
+ var $shortname = 'pocket';
+
+ public function __construct( $id, array $settings ) {
+ parent::__construct( $id, $settings );
+
+ if ( 'official' == $this->button_style )
+ $this->smart = true;
+ else
+ $this->smart = false;
+ }
+
+ public function get_name() {
+ return __( 'Pocket', 'jetpack' );
+ }
+
+ public function process_request( $post, array $post_data ) {
+ // Record stats
+ parent::process_request( $post, $post_data );
+
+ $pocket_url = esc_url_raw( 'https://getpocket.com/save/?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $post->post_title ) );
+ wp_redirect( $pocket_url );
+ exit;
+ }
+
+ public function get_display( $post ) {
+ if ( $this->smart ) {
+ $post_count = 'horizontal';
+
+ $button = '';
+ $button .= '<div class="pocket_button">';
+ $button .= sprintf( '<a href="https://getpocket.com/save" class="pocket-btn" data-lang="%s" data-save-url="%s" data-pocket-count="%s" >%s</a>', 'en', esc_attr( $this->get_share_url( $post->ID ) ), $post_count, esc_attr__( 'Pocket', 'jetpack' ) );
+ $button .= '</div>';
+
+ return $button;
+ } else {
+ return $this->get_link( get_permalink( $post->ID ), _x( 'Pocket', 'share to', 'jetpack' ), __( 'Click to share on Pocket', 'jetpack' ), 'share=pocket' );
+ }
+
+ }
+
+ function display_footer() {
+ if ( $this->smart ) :
+ ?>
+ <script>
+ // Don't use Pocket's default JS as it we need to force init new Pocket share buttons loaded via JS.
+ function jetpack_sharing_pocket_init() {
+ jQuery.getScript( 'https://widgets.getpocket.com/v1/j/btn.js?v=1' );
+ }
+ jQuery( document ).on( 'ready', jetpack_sharing_pocket_init );
+ jQuery( document.body ).on( 'post-load', jetpack_sharing_pocket_init );
+ </script>
+ <?php
+ else :
+ $this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
+ endif;
+
+ }
+
+}
+
diff --git a/plugins/jetpack/modules/sharedaddy/sharing.css b/plugins/jetpack/modules/sharedaddy/sharing.css
index 95a09d0e..1d1719c8 100644
--- a/plugins/jetpack/modules/sharedaddy/sharing.css
+++ b/plugins/jetpack/modules/sharedaddy/sharing.css
@@ -1,4 +1,4 @@
-div.sharedaddy ul,
+li.share-print a.sd-button > spandiv.sharedaddy ul,
div.sharedaddy li {
margin: 0;
padding: 0;
@@ -7,15 +7,15 @@ div.sharedaddy li {
background: none;
}
-div.sharedaddy,
-#content div.sharedaddy,
+div.sharedaddy,
+#content div.sharedaddy,
#main div.sharedaddy {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12px;
clear: both;
}
-div.sharedaddy,
+div.sharedaddy,
div.sharedaddy div {
-webkit-border-radius: 0 !important;
-moz-border-radius: 0 !important;
@@ -41,7 +41,7 @@ div.sharedaddy h3,
}
/* @noflip */
-.rtl div.sharedaddy h3,
+.rtl div.sharedaddy h3,
.rtl #content div.sharedaddy h3,
.rtl #main div.sharedaddy h3,
.rtl #primary div.sharedaddy h3 {
@@ -49,7 +49,7 @@ div.sharedaddy h3,
text-align: right;
}
-div.sharedaddy ul,
+div.sharedaddy ul,
div.sharedaddy li {
margin: 0 !important;
padding: 0 !important;
@@ -60,29 +60,24 @@ div.sharedaddy li::before {
content: "";
}
-div.sharedaddy div.sharing-clear {
- margin: 0 !important;
- padding: 0 !important;
-}
-
div.sharedaddy div.pd-rating {
margin: 0;
min-height: 23px;
}
-div.sharedaddy a,
-div.sharedaddy a:link,
+div.sharedaddy a,
+div.sharedaddy a:link,
div.sharedaddy a:visited {
font-style: normal;
}
/* ClearFix trick */
-div.sharedaddy:before,
+div.sharedaddy:before,
div.sharedaddy:after,
-div.sharedaddy .sd-block:before,
+div.sharedaddy .sd-block:before,
div.sharedaddy .sd-block:after,
-div.sharedaddy ul:before,
+div.sharedaddy ul:before,
div.sharedaddy ul:after {
content: "\0020";
display: block;
@@ -120,7 +115,7 @@ div.sharedaddy.sharedaddy-dark .sd-block {
}
div.sharedaddy .sd-content {
- width: 82.125%; /* 530px / 640px */
+ width: 82.125%; /* 530px / 640px */
float: right;
margin: -2px 0 0 0;
}
@@ -315,6 +310,14 @@ li.share-pinterest a.sd-button > span {
background-image: url('images/pinterest.png');
}
+li.share-pocket a.sd-button > span {
+ background-image: url('images/pocket.png');
+}
+
+li.share-kindle a.sd-button > span {
+ background-image: url('images/kindle.png');
+}
+
li.share-email a.sd-button > span {
background-image: url('images/email.png');
}
@@ -327,23 +330,23 @@ a.sd-button.share-more span {
background-image: url('images/more.png');
}
-@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
+@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5), only screen and (min-resolution: 120dpi) {
li.share-facebook a.sd-button > span {
background-image: url('images/facebook@2x.png');
background-size: 16px 16px;
}
-
+
li.share-tumblr a.sd-button > span {
background-image: url('images/tumblr@2x.png');
background-size: 16px 16px;
}
-
+
li.share-twitter a.sd-button > span {
background-image: url('images/twitter@2x.png?1');
background-size: 16px 16px;
}
-
+
li.share-google-plus-1 a.sd-button > span {
background-image: url('images/googleplus1@2x.png');
background-size: 16px 16px;
@@ -353,42 +356,52 @@ a.sd-button.share-more span {
background-image: url('images/linkedin@2x.png');
background-size: 16px 16px;
}
-
+
li.share-press-this a.sd-button > span {
background-image: url('images/wordpress@2x.png');
background-size: 16px 16px;
}
-
+
li.share-digg a.sd-button > span {
background-image: url('images/digg@2x.png?1');
background-size: 16px 16px;
}
-
+
li.share-stumbleupon a.sd-button > span {
background-image: url('images/stumbleupon@2x.png');
background-size: 16px 16px;
}
-
+
li.share-reddit a.sd-button > span {
background-image: url('images/reddit@2x.png');
background-size: 16px 16px;
}
-
+
li.share-pinterest a.sd-button > span {
background-image: url('images/pinterest@2x.png');
background-size: 16px 16px;
}
-
+
+ li.share-pocket a.sd-button > span {
+ background-image: url('images/pocket@2x.png');
+ background-size: 16px 16px;
+ }
+
+ li.share-kindle a.sd-button > span {
+ background-image: url('images/kindle@2x.png');
+ background-size: 16px 16px;
+ }
+
li.share-email a.sd-button > span {
background-image: url('images/email@2x.png?1');
background-size: 16px 16px;
}
-
+
li.share-print a.sd-button > span {
background-image: url('images/print@2x.png');
background-size: 16px 16px;
}
-
+
a.sd-button.share-more span {
background-image: url('images/more@2x.png?1');
background-size: 16px 16px;
diff --git a/plugins/jetpack/modules/sharedaddy/sharing.js b/plugins/jetpack/modules/sharedaddy/sharing.js
index 68482c60..c996bb6f 100644
--- a/plugins/jetpack/modules/sharedaddy/sharing.js
+++ b/plugins/jetpack/modules/sharedaddy/sharing.js
@@ -71,7 +71,7 @@ var WPCOMSharing = {
// Touchscreen device: use click.
// Non-touchscreen device: use click if not already appearing due to a hover event
- $more_sharing_buttons.click( function() {
+ $more_sharing_buttons.on( 'click', function() {
var $more_sharing_button = $( this ),
$more_sharing_pane = $more_sharing_button.parents( 'div:first' ).find( '.inner' );
@@ -183,6 +183,11 @@ var WPCOMSharing = {
// Add click functionality
$( '.sharedaddy ul' ).each( function( item ) {
+
+ if ( 'yep' == $( this ).data( 'has-click-events' ) )
+ return;
+ $( this ).data( 'has-click-events', 'yep' );
+
printUrl = function ( uniqueId, urlToPrint ) {
$( 'body:first' ).append( '<iframe style="position:fixed;top:100;left:100;height:1px;width:1px;border:none;" id="printFrame-' + uniqueId + '" name="printFrame-' + uniqueId + '" src="' + urlToPrint + '" onload="frames[\'printFrame-' + uniqueId + '\'].focus();frames[\'printFrame-' + uniqueId + '\'].print();"></iframe>' )
};
@@ -233,7 +238,7 @@ var WPCOMSharing = {
} );
// Email button
- $( this ).find( 'a.share-email' ).click( function() {
+ $( 'a.share-email', this ).on( 'click', function() {
var url = $( this ).attr( 'href' ), key;
if ( $( '#sharing_email' ).is( ':visible' ) )
@@ -251,7 +256,7 @@ var WPCOMSharing = {
key = $( '#recaptcha_public_key' ).val();
// Update the recaptcha
- Recaptcha.create( key, 'sharing_recaptcha' );
+ Recaptcha.create( key, 'sharing_recaptcha', { lang : recaptcha_options.lang } );
// Show dialog
$( '#sharing_email' ).css( {
diff --git a/plugins/jetpack/modules/sharedaddy/sharing.php b/plugins/jetpack/modules/sharedaddy/sharing.php
index 118f851c..974fe741 100644
--- a/plugins/jetpack/modules/sharedaddy/sharing.php
+++ b/plugins/jetpack/modules/sharedaddy/sharing.php
@@ -281,7 +281,6 @@ class Sharing_Admin {
endforeach; ?>
<li class="advanced"><a href="#" class="sharing-anchor sd-button share-more"><span><?php _e( 'More', 'jetpack' ); ?></span></a></li>
</ul>
- <div class="sharing-clear"></div>
</div>
</div>
<br class="clearing" />
diff --git a/plugins/jetpack/modules/shortcodes.php b/plugins/jetpack/modules/shortcodes.php
index e10805ca..ce54d632 100644
--- a/plugins/jetpack/modules/shortcodes.php
+++ b/plugins/jetpack/modules/shortcodes.php
@@ -6,6 +6,7 @@
* Sort Order: 11
* First Introduced: 1.1
* Major Changes In: 1.2
+ * Requires Connection: No
*/
/**
@@ -21,7 +22,7 @@
*/
function shortcode_new_to_old_params( $params, $old_format_support = false ) {
$str = '';
-
+
if ( $old_format_support && isset( $params[0] ) ) {
$str = ltrim( $params[0], '=' );
} elseif ( is_array( $params ) ) {
@@ -30,13 +31,39 @@ function shortcode_new_to_old_params( $params, $old_format_support = false ) {
$str = $key . '=' . $params[$key];
}
}
-
- return str_replace( array( '&amp;', '&#038;' ), '&', $str );
+
+ return str_replace( array( '&amp;', '&#038;' ), '&', $str );
}
function jetpack_load_shortcodes() {
+ global $wp_version;
+
+ $shortcode_includes = array();
+
foreach ( Jetpack::glob_php( dirname( __FILE__ ) . '/shortcodes' ) as $file ) {
- include $file;
+ $shortcode_includes[] = $file;
+ }
+
+ $shortcode_includes = apply_filters( 'jetpack_shortcodes_to_include', $shortcode_includes );
+
+ foreach ( $shortcode_includes as $include ) {
+ if ( version_compare( $wp_version, '3.6-z', '>=' ) && stristr( $include, 'audio.php' ) )
+ continue;
+
+ include $include;
+ }
+}
+
+global $wp_version;
+
+if ( version_compare( $wp_version, '3.6-z', '>=' ) ) {
+ add_filter( 'shortcode_atts_audio', 'jetpack_audio_atts_handler', 10, 3 );
+
+ function jetpack_audio_atts_handler( $out, $pairs, $atts ) {
+ if( isset( $atts[0] ) )
+ $out['src'] = $atts[0];
+
+ return $out;
}
}
diff --git a/plugins/jetpack/modules/shortcodes/archives.php b/plugins/jetpack/modules/shortcodes/archives.php
index b4c78f3c..c407978f 100644
--- a/plugins/jetpack/modules/shortcodes/archives.php
+++ b/plugins/jetpack/modules/shortcodes/archives.php
@@ -3,7 +3,7 @@
/*
* Archives shortcode
* @author bubel & nickmomrik
- * [archives limit=10]
+ * [archives limit=10]
*/
add_shortcode( 'archives', 'archives_shortcode' );
diff --git a/plugins/jetpack/modules/shortcodes/audio.php b/plugins/jetpack/modules/shortcodes/audio.php
index 9c6b49eb..744cf49c 100644
--- a/plugins/jetpack/modules/shortcodes/audio.php
+++ b/plugins/jetpack/modules/shortcodes/audio.php
@@ -17,6 +17,16 @@ class AudioShortcode {
}
/**
+ * Return the $url of the audio
+ */
+ static function get_audio_id( $atts ) {
+ if ( isset( $atts[0] ) )
+ return $atts[0];
+ else
+ return 0;
+ }
+
+ /**
* Shortcode for audio
* [audio http://wpcom.files.wordpress.com/2007/01/mattmullenweg-interview.mp3|width=180|titles=1|artists=2]
*
@@ -31,7 +41,12 @@ class AudioShortcode {
}
if ( ! isset( $atts[0] ) ) {
- return '<!-- Audio shortcode source not set -->';
+ if ( isset( $atts['src'] ) ) {
+ $atts[0] = $atts['src'];
+ unset( $atts['src'] );
+ } else {
+ return '<!-- Audio shortcode source not set -->';
+ }
}
// add the special .js
@@ -79,6 +94,13 @@ class AudioShortcode {
$data = preg_split( "/\|/", $src );
$sound_file = $data[0];
$sound_files = explode( ',', $sound_file );
+
+ if ( is_ssl() ) {
+ for ( $i = 0; $i < count( $sound_files ); $i++ ) {
+ $sound_files[ $i ] = preg_replace( '#^http://([^.]+).files.wordpress.com/#', 'https://$1.files.wordpress.com/', $sound_files[ $i ] );
+ }
+ }
+
$sound_files = array_map( 'trim', $sound_files );
$sound_files = array_map( array( $this, 'rawurlencode_spaces' ), $sound_files );
$sound_files = array_map( 'esc_url_raw', $sound_files ); // Ensure each is a valid URL
@@ -232,9 +254,14 @@ CONTROLS;
}
$html5_audio .= "<span id='wp-as-{$post->ID}_{$ap_playerID}-playing'></span>";
+ if ( is_ssl() )
+ $protocol = 'https';
+ else
+ $protocol = 'http';
+
$swfurl = apply_filters(
'jetpack_static_url',
- 'http://en.wordpress.com/wp-content/plugins/audio-player/player.swf' );
+ "$protocol://en.wordpress.com/wp-content/plugins/audio-player/player.swf" );
// all the fancy javascript is causing Google Reader to break, just include flash in GReader
// override html5 audio code w/ just not supported code
diff --git a/plugins/jetpack/modules/shortcodes/blip.php b/plugins/jetpack/modules/shortcodes/blip.php
index e757dc4b..0245522a 100644
--- a/plugins/jetpack/modules/shortcodes/blip.php
+++ b/plugins/jetpack/modules/shortcodes/blip.php
@@ -2,10 +2,10 @@
/**
* Blip.tv embed code:
- * <embed src="http://blip.tv/play/g8sVgpfaCgI%2Em4v" type="application/x-shockwave-flash" width="480" height="255" allowscriptaccess="always" allowfullscreen="true"></embed>
+ * <embed src="http://blip.tv/play/g8sVgpfaCgI%2Em4v" type="application/x-shockwave-flash" width="480" height="255" allowscriptaccess="always" allowfullscreen="true"></embed>
* Blip.tv shortcode is: [blip.tv url-or-something-else]
* */
-
+
function blip_embed_to_shortcode( $content ) {
if ( false === stripos( $content, '/blip.tv/play/' ) )
return $content;
@@ -47,7 +47,7 @@ function blip_shortcode( $atts ) {
return "<script type='text/javascript' src='http://blip.tv/syndication/write_player?skin=js&posts_id={$matches[1]}&cross_post_destination={$matches[2]}&view=full_js'></script>";
elseif ( preg_match( '|^http://blip.tv/play/[.\w]+$|', urldecode( $src ) ) ) // WLS
return "<embed src='$src' type='application/x-shockwave-flash' width='480' height='300' allowscriptaccess='never' allowfullscreen='true'></embed>";
-
+
return "<!--blip.tv pattern not matched -->";
}
diff --git a/plugins/jetpack/modules/shortcodes/css/rtl/slideshow-shortcode-rtl.css b/plugins/jetpack/modules/shortcodes/css/rtl/slideshow-shortcode-rtl.css
index 167ec706..eea868af 100644
--- a/plugins/jetpack/modules/shortcodes/css/rtl/slideshow-shortcode-rtl.css
+++ b/plugins/jetpack/modules/shortcodes/css/rtl/slideshow-shortcode-rtl.css
@@ -1,4 +1,4 @@
-/* This file was automatically generated on Jan 06 2013 05:39:50 */
+/* This file was automatically generated on Mar 25 2013 08:14:36 */
.slideshow-window {
background-color: #222;
@@ -25,6 +25,8 @@
body div.slideshow-window * img {
/* Override any styles that might be present in the page stylesheet */
border-width: 0 !important;
+ margin-left: auto !important;
+ margin-right: auto !important;
padding: 0 !important;
background-color: transparent !important;
background-image: none !important;
diff --git a/plugins/jetpack/modules/shortcodes/css/slideshow-shortcode.css b/plugins/jetpack/modules/shortcodes/css/slideshow-shortcode.css
index e6d05b23..13cef497 100644
--- a/plugins/jetpack/modules/shortcodes/css/slideshow-shortcode.css
+++ b/plugins/jetpack/modules/shortcodes/css/slideshow-shortcode.css
@@ -23,6 +23,8 @@
body div.slideshow-window * img {
/* Override any styles that might be present in the page stylesheet */
border-width: 0 !important;
+ margin-right: auto !important;
+ margin-left: auto !important;
padding: 0 !important;
background-color: transparent !important;
background-image: none !important;
diff --git a/plugins/jetpack/modules/shortcodes/dailymotion.php b/plugins/jetpack/modules/shortcodes/dailymotion.php
index a6daed9d..fe2e6ab6 100644
--- a/plugins/jetpack/modules/shortcodes/dailymotion.php
+++ b/plugins/jetpack/modules/shortcodes/dailymotion.php
@@ -6,13 +6,13 @@
/**
* Original codes:
- *
+ *
* <embed height="270" type="application/x-shockwave-flash" width="480" src="http&#58;//www.dailymotion.com/swf/video/xekmrq?additionalInfos=0" wmode="opaque" pluginspage="http&#58;//www.macromedia.com/go/getflashplayer" allowscriptaccess="never" allownetworking="internal" />
*
* <object width="480" height="240"><param name="movie" value="http://www.dailymotion.com/swf/video/xen4ms_ghinzu-cold-love-mirror-mirror_music?additionalInfos=0"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param>
* <embed type="application/x-shockwave-flash" src="http://www.dailymotion.com/swf/video/xen4ms_ghinzu-cold-love-mirror-mirror_music?additionalInfos=0" width="480" height="240" allowfullscreen="true" allowscriptaccess="always"></embed>
* </object><br /><b><a href="http://www.dailymotion.com/video/xen4ms_ghinzu-cold-love-mirror-mirror_music">Ghinzu - Cold Love (Mirror Mirror)</a></b><br /><i>Uploaded by <a href="http://www.dailymotion.com/GhinzuTV">GhinzuTV</a>. - <a href="http://www.dailymotion.com/us/channel/music">Watch more music videos, in HD!</a></i>
- *
+ *
* Code as of 01.01.11:
* <object width="560" height="421"><param name="movie" value="http://www.dailymotion.com/swf/video/xaose5?width=560&theme=denim&foreground=%2392ADE0&highlight=%23A2ACBF&background=%23202226&start=&animatedTitle=&iframe=0&additionalInfos=0&autoPlay=0&hideInfos=0"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed type="application/x-shockwave-flash" src="http://www.dailymotion.com/swf/video/xaose5?width=560&theme=denim&foreground=%2392ADE0&highlight=%23A2ACBF&background=%23202226&start=&animatedTitle=&iframe=0&additionalInfos=0&autoPlay=0&hideInfos=0" width="560" height="421" allowfullscreen="true" allowscriptaccess="always"></embed></object><br /><b><a href="http://www.dailymotion.com/video/xaose5_sexy-surprise_na">Sexy Surprise</a></b><br /><i>Uploaded by <a href="http://www.dailymotion.com/GilLavie">GilLavie</a>. - <a target="_self" href="http://www.dailymotion.com/channel/sexy/featured/1">Find more steamy, sexy videos.</a></i>
* movie param enforces anti-xss protection
@@ -53,29 +53,29 @@ add_filter( 'pre_kses', 'dailymotion_embed_to_shortcode' );
/**
* DailyMotion shortcode
- *
- * The documented shortcode is:
- * [dailymotion id=x8oma9]
- *
+ *
+ * The documented shortcode is:
+ * [dailymotion id=x8oma9]
+ *
* Possibilities, according to the old parsing regexp:
* [dailymotion x8oma9]
- * [dailymotion=x8oma9]
- *
+ * [dailymotion=x8oma9]
+ *
* Hypothetical option, according to the old shortcode function is
* [dailymotion id=1&title=2&user=3&video=4]
- *
- * The new style is now:
- * [dailymotion id=x8oma9 title=2 user=3 video=4]
- *
+ *
+ * The new style is now:
+ * [dailymotion id=x8oma9 title=2 user=3 video=4]
+ *
* @param array $atts
- * @return string html
+ * @return string html
*
- */
+ */
function dailymotion_shortcode( $atts ) {
global $content_width;
- if ( isset( $atts[0] ) ) {
+ if ( isset( $atts[0] ) ) {
$id = ltrim( $atts[0], '=' );
$atts['id'] = $id;
} else {
@@ -85,7 +85,7 @@ function dailymotion_shortcode( $atts ) {
if ( isset( $atts['id'] ) )
$id = $atts['id'];
- else
+ else
return '<!--Dailymotion error: bad or missing ID-->';
if ( !empty( $content_width ) )
diff --git a/plugins/jetpack/modules/shortcodes/diggthis.php b/plugins/jetpack/modules/shortcodes/diggthis.php
index ee1195fa..0077a468 100644
--- a/plugins/jetpack/modules/shortcodes/diggthis.php
+++ b/plugins/jetpack/modules/shortcodes/diggthis.php
@@ -1,17 +1,17 @@
<?php
/**
- * Digg changed their button API.
- *
+ * Digg changed their button API.
+ *
* The old style button was something like this:
* [digg=http://digg.com/some-digg-permalink] - uses digg permalink as id.
- *
+ *
* The new style is:
- * [digg class="wide"] # The class options are: 'wide', 'medium', 'compact', 'icon'
+ * [digg class="wide"] # The class options are: 'wide', 'medium', 'compact', 'icon'
* and uses get_permalink() as id.
- *
- * @author Veselin Nikolov
- */
+ *
+ * @author Veselin Nikolov
+ */
function digg_shortcode_js() {
echo '
diff --git a/plugins/jetpack/modules/shortcodes/flickr.php b/plugins/jetpack/modules/shortcodes/flickr.php
index 6a85f4cb..3f1b13c5 100644
--- a/plugins/jetpack/modules/shortcodes/flickr.php
+++ b/plugins/jetpack/modules/shortcodes/flickr.php
@@ -12,8 +12,8 @@
*/
-/*
- * <object type="application/x-shockwave-flash" width="400" height="300" data="http://www.flickr.com/apps/video/stewart.swf?v=71377" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param name="flashvars" value="intl_lang=en-us&photo_secret=846d9c1be9&photo_id=2345938910"></param> <param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=71377"></param> <param name="bgcolor" value="#000000"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=71377" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&photo_secret=846d9c1be9&photo_id=2345938910" height="300" width="400"></embed></object>
+/*
+ * <object type="application/x-shockwave-flash" width="400" height="300" data="http://www.flickr.com/apps/video/stewart.swf?v=71377" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param name="flashvars" value="intl_lang=en-us&photo_secret=846d9c1be9&photo_id=2345938910"></param> <param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=71377"></param> <param name="bgcolor" value="#000000"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=71377" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&photo_secret=846d9c1be9&photo_id=2345938910" height="300" width="400"></embed></object>
*/
function flickr_embed_to_shortcode( $content ) {
@@ -94,7 +94,7 @@ function flickr_shortcode_handler( $atts ) {
if ( isset( $atts['video'] ) ) {
$showing = 'video';
- $src = $atts['video'];
+ $src = $atts['video'];
} elseif ( isset( $atts['photo'] ) ) {
$showing = 'photo';
$src = $atts['photo'];
@@ -113,7 +113,7 @@ function flickr_shortcode_handler( $atts ) {
elseif ( in_array( $atts['show_info'], array( 'false', 'no' ) ) )
$atts['show_info'] = 'false';
- if ( isset( $atts['secret'] ) )
+ if ( isset( $atts['secret'] ) )
$atts['secret'] = preg_replace( '![^\w]+!i', '', $atts['secret'] );
return flickr_shortcode_video_markup( $atts );
@@ -125,7 +125,7 @@ function flickr_shortcode_handler( $atts ) {
function flickr_shortcode_video_markup( $atts ) {
$atts = array_map( 'esc_attr', $atts );
- $photo_vars = "photo_id=$atts[photo_id]";
+ $photo_vars = "photo_id=$atts[photo_id]";
if ( isset( $atts['secret'] ) )
$photo_vars .= "&amp;photo_secret=$atts[secret]";
diff --git a/plugins/jetpack/modules/shortcodes/googlemaps.php b/plugins/jetpack/modules/shortcodes/googlemaps.php
index fe79a9e6..224654fa 100644
--- a/plugins/jetpack/modules/shortcodes/googlemaps.php
+++ b/plugins/jetpack/modules/shortcodes/googlemaps.php
@@ -75,6 +75,10 @@ function jetpack_googlemaps_shortcode( $atts ) {
}
}
$url = substr( $url, 0, -5 );
+
+ if( is_ssl() )
+ $url = str_replace( 'http://', 'https://', $url );
+
$link_url = preg_replace( '!output=embed!', 'source=embed', $url );
return '<div class="googlemaps"><iframe width="' . $width . '" height="' . $height . '" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="' . $url . '"></iframe><br /><small><a href="' . $link_url . '" style="text-align:left">View Larger Map</a></small></div>';
diff --git a/plugins/jetpack/modules/shortcodes/googlevideo.php b/plugins/jetpack/modules/shortcodes/googlevideo.php
index 83074fbf..cbd709c9 100644
--- a/plugins/jetpack/modules/shortcodes/googlevideo.php
+++ b/plugins/jetpack/modules/shortcodes/googlevideo.php
@@ -2,7 +2,7 @@
/**
* google video is replaced by youtube, but its embeds will probably continue working indefinitely.
- * [googlevideo=http://video.google.com/googleplayer.swf?docId=-6006084025483872237]
+ * [googlevideo=http://video.google.com/googleplayer.swf?docId=-6006084025483872237]
*/
function googlevideo_shortcode( $atts ) {
@@ -10,7 +10,7 @@ function googlevideo_shortcode( $atts ) {
return '';
$src = ltrim( $atts[0], '=' );
-
+
if ( 0 !== strpos( $src, 'http://video.google.com/googleplayer.swf' ) ) {
if ( !preg_match( '|^http://(video\.google\.[a-z]{2,3}(?:.[a-z]{2})?)/|', $src ) || !preg_match( '|.*docid=([0-9-]+).*|i', $src, $match ) || !is_numeric( $match[1] ) )
return '<!--Google Video Error: bad URL entered-->';
diff --git a/plugins/jetpack/modules/shortcodes/js/audio-shortcode.js b/plugins/jetpack/modules/shortcodes/js/audio-shortcode.js
index 7697258e..400219e4 100644
--- a/plugins/jetpack/modules/shortcodes/js/audio-shortcode.js
+++ b/plugins/jetpack/modules/shortcodes/js/audio-shortcode.js
@@ -50,7 +50,7 @@ window.audioshortcode = {
}
// bail if there are no more good files
- if ( 0 == this[player_id].files.length ) {
+ if ( 0 === this[player_id].files.length ) {
return;
}
player.src = this[player_id].files[0];
@@ -64,7 +64,7 @@ window.audioshortcode = {
audioshortcode.remove_track( player_id, audioshortcode[player_id].i );
if ( 0 < audioshortcode[player_id].files.length ) {
audioshortcode[player_id].i--;
- audioshortcode.next_track( player_id, false, loop );
+ audioshortcode.next_track( player_id, false, loop );
}
}, false );
@@ -91,7 +91,7 @@ window.audioshortcode = {
this[player_id].titles.splice( index, 1 );
// get rid of player/controls if they can't be played
- if ( 0 == this[player_id].files.length ) {
+ if ( 0 === this[player_id].files.length ) {
$( '#wp-as-' + player_id + '-container' ).html( $( '#wp-as-' + player_id + '-nope' ).html() );
$( '#wp-as-' + player_id + '-controls' ).html( '' );
} else if ( 1 == this[player_id].files.length ) {
@@ -115,9 +115,9 @@ window.audioshortcode = {
prev_track: function( player_id ) {
var player = $( '#wp-as-' + player_id ).get(0);
var files = this[player_id].files;
- if ( player.paused || 0 == this[player_id].i ) {
- return
- };
+ if ( player.paused || 0 === this[player_id].i ) {
+ return;
+ }
player.pause();
if ( 0 < this[player_id].i ) {
diff --git a/plugins/jetpack/modules/shortcodes/js/jquery.cycle.js b/plugins/jetpack/modules/shortcodes/js/jquery.cycle.js
index 89d583eb..d12df1ba 100644
--- a/plugins/jetpack/modules/shortcodes/js/jquery.cycle.js
+++ b/plugins/jetpack/modules/shortcodes/js/jquery.cycle.js
@@ -22,7 +22,7 @@ if ($.support === undefined) {
function debug(s) {
if ($.fn.cycle.debug)
log(s);
-}
+}
function log() {
if (window.console && console.log)
console.log('[cycle] ' + Array.prototype.join.call(arguments,' '));
@@ -66,7 +66,7 @@ $.fn.cycle = function(options, arg2) {
return;
opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink;
-
+
// stop existing slideshow for this container (if there is one)
if (this.cycleTimeout)
clearTimeout(this.cycleTimeout);
@@ -184,7 +184,7 @@ function handleArguments(cont, options, arg2) {
return false;
}
return options;
-
+
function checkInstantResume(isPaused, arg2, cont) {
if (!isPaused && arg2 === true) { // resume now!
var options = $(cont).data('cycle.opts');
@@ -214,7 +214,7 @@ function destroy(cont, opts) {
$(opts.next).unbind(opts.prevNextEvent);
if (opts.prev)
$(opts.prev).unbind(opts.prevNextEvent);
-
+
if (opts.pager || opts.pagerAnchorBuilder)
$.each(opts.pagerAnchors || [], function() {
this.unbind().remove();
@@ -268,7 +268,7 @@ function buildOptions($cont, $slides, els, options, o) {
opts.startingSlide = parseInt(opts.startingSlide,10);
if (opts.startingSlide >= els.length || opts.startSlide < 0)
opts.startingSlide = 0; // catch bogus input
- else
+ else
startingSlideSpecified = true;
}
else if (opts.backwards)
@@ -361,7 +361,7 @@ function buildOptions($cont, $slides, els, options, o) {
});
});
}
-
+
// stretch container
var reshape = (opts.containerResize || opts.containerResizeHeight) && !$cont.innerHeight();
if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9
@@ -447,7 +447,7 @@ function buildOptions($cont, $slides, els, options, o) {
opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10);
if (!opts.sync)
opts.speed = opts.speed / 2;
-
+
var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250;
while((opts.timeout - opts.speed) < buffer) // sanitize timeout
opts.timeout += opts.speed;
@@ -705,7 +705,7 @@ function go(els, opts, manual, fwd) {
};
debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide);
-
+
// get ready to perform the transition
opts.busy = 1;
if (opts.fxFn) // fx function provided?
@@ -760,7 +760,7 @@ function go(els, opts, manual, fwd) {
}
if (changed && opts.pager)
opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass);
-
+
function queueNext() {
// stage the next transition
var ms = 0, timeout = opts.timeout;
@@ -857,7 +857,7 @@ $.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
}
else
a = '<a href="#">'+(i+1)+'</a>';
-
+
if (!a)
return;
var $a = $(a);
@@ -879,7 +879,7 @@ $.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
opts.pagerAnchors = opts.pagerAnchors || [];
opts.pagerAnchors.push($a);
-
+
var pagerFn = function(e) {
e.preventDefault();
opts.nextSlide = i;
@@ -894,30 +894,30 @@ $.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
go(els,opts,1,opts.currSlide < i); // trigger the trans
// return false; // <== allow bubble
};
-
+
if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) {
$a.hover(pagerFn, function(){/* no-op */} );
}
else {
$a.bind(opts.pagerEvent, pagerFn);
}
-
+
if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble)
$a.bind('click.cycle', function(){return false;}); // suppress click
-
+
var cont = opts.$cont[0];
var pauseFlag = false; // https://github.com/malsup/cycle/issues/44
if (opts.pauseOnPagerHover) {
$a.hover(
- function() {
+ function() {
pauseFlag = true;
- cont.cyclePause++;
+ cont.cyclePause++;
triggerPause(cont,true,true);
- }, function() {
+ }, function() {
if (pauseFlag)
- cont.cyclePause--;
+ cont.cyclePause--;
triggerPause(cont,true,true);
- }
+ }
);
}
};
@@ -990,7 +990,7 @@ $.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) {
};
$l.animate(opts.animOut, speedOut, easeOut, function() {
$l.css(opts.cssAfter);
- if (!opts.sync)
+ if (!opts.sync)
fn();
});
if (opts.sync) fn();
diff --git a/plugins/jetpack/modules/shortcodes/polldaddy.php b/plugins/jetpack/modules/shortcodes/polldaddy.php
index 7eb30edf..6b46da7f 100644
--- a/plugins/jetpack/modules/shortcodes/polldaddy.php
+++ b/plugins/jetpack/modules/shortcodes/polldaddy.php
@@ -8,7 +8,7 @@ class PolldaddyShortcode {
static $add_script = false;
static $scripts = false;
-
+
/**
* Add all the actions & resgister the shortcode
*/
@@ -27,7 +27,7 @@ class PolldaddyShortcode {
function polldaddy_shortcode( $atts ) {
global $post;
global $content_width;
-
+
extract( shortcode_atts( array(
'survey' => null,
'link_text' => 'Take Our Survey',
@@ -52,48 +52,48 @@ class PolldaddyShortcode {
'domain' => '',
'id' => ''
), $atts ) );
-
+
if ( ! is_array( $atts ) ) {
return '<!-- Polldaddy shortcode passed invalid attributes -->';
}
-
+
$inline = false;
$no_script = false;
$infinite_scroll = false;
-
+
if ( is_home() && current_theme_supports( 'infinite-scroll' ) )
$infinite_scroll = true;
-
+
if ( defined( 'PADPRESS_LOADED' ) )
$inline = true;
-
+
if ( function_exists( 'get_option' ) && get_option( 'polldaddy_load_poll_inline' ) )
$inline = true;
-
+
if ( is_feed() || ( defined( 'DOING_AJAX' ) && !$infinite_scroll ) )
$no_script = false;
-
+
self::$add_script = $infinite_scroll;
-
- if ( intval( $rating ) > 0 && !$no_script ) { //rating embed
-
+
+ if ( intval( $rating ) > 0 && !$no_script ) { //rating embed
+
if ( empty( $unique_id ) )
$unique_id = is_page() ? 'wp-page-'.$post->ID : 'wp-post-'.$post->ID;
-
+
if ( empty( $item_id ) )
$item_id = is_page() ? '_page_'.$post->ID : '_post_'.$post->ID;
-
+
if ( empty( $title ) )
$title = apply_filters( 'wp_title', $post->post_title, '', '' );
-
+
if ( empty( $permalink ) )
$permalink = get_permalink( $post->ID );
-
+
$rating = intval( $rating );
$unique_id = wp_strip_all_tags( $unique_id );
$item_id = wp_strip_all_tags( $item_id );
$item_id = preg_replace( '/[^_a-z0-9]/i', '', $item_id );
-
+
$settings = json_encode( array(
'id' => $rating,
'unique_id' => $unique_id,
@@ -101,10 +101,10 @@ class PolldaddyShortcode {
'permalink' => esc_url( $permalink ),
'item_id' => $item_id
) );
-
+
$item_id = esc_js( $item_id );
-
- if ( $inline ) {
+
+ if ( $inline ) {
return <<<SCRIPT
<div class="pd-rating" id="pd_rating_holder_{$rating}{$item_id}"></div>
<script type="text/javascript" charset="UTF-8"><!--//--><![CDATA[//><!--
@@ -113,18 +113,18 @@ PDRTJS_settings_{$rating}{$item_id}={$settings};
<script type="text/javascript" charset="UTF-8" src="http://i.polldaddy.com/ratings/rating.js"></script>
SCRIPT;
}
- else {
+ else {
if ( self::$scripts === false )
self::$scripts = array();
-
+
$data = array( 'id' => $rating, 'item_id' => $item_id, 'settings' => $settings );
-
+
self::$scripts['rating'][] = $data;
-
+
add_action( 'wp_footer', array( $this, 'generate_scripts' ) );
-
+
$data = esc_attr( json_encode( $data ) );
-
+
if ( $infinite_scroll )
return <<<CONTAINER
<div class="pd-rating" id="pd_rating_holder_{$rating}{$item_id}" data-settings="{$data}"></div>
@@ -134,22 +134,22 @@ CONTAINER;
<div class="pd-rating" id="pd_rating_holder_{$rating}{$item_id}"></div>
CONTAINER;
}
- }
+ }
elseif ( intval( $poll ) > 0 ) { //poll embed
-
+
$poll = intval( $poll );
$poll_url = sprintf( 'http://polldaddy.com/poll/%d', $poll );
$poll_js = sprintf( '%s.polldaddy.com/p/%d.js', ( is_ssl() ? 'https://secure' : 'http://static' ), $poll );
$poll_link = sprintf( '<a href="%s">Take Our Poll</a>', $poll_url );
-
+
if ( $no_script )
return $poll_link;
else {
if ( $type == 'slider' && !$inline ) {
-
+
if( !in_array( $visit, array( 'single', 'multiple' ) ) )
$visit = 'single';
-
+
$settings = json_encode( array(
'type' => 'slider',
'embed' => 'poll',
@@ -157,7 +157,7 @@ CONTAINER;
'visit' => $visit,
'id' => intval( $poll )
) );
-
+
return <<<SCRIPT
<script type="text/javascript" charset="UTF-8" src="http://i0.poll.fm/survey.js"></script>
<script type="text/javascript" charset="UTF-8"><!--//--><![CDATA[//><!--
@@ -170,28 +170,28 @@ SCRIPT;
$cb = ( $cb == 1 ? '?cb='.mktime() : false );
$margins = '';
$float = '';
-
+
if ( in_array( $align, array( 'right', 'left' ) ) ) {
- $float = sprintf( 'float: %s;', $align );
-
+ $float = sprintf( 'float: %s;', $align );
+
if ( $align == 'left')
$margins = 'margin: 0px 10px 0px 0px;';
elseif ( $align == 'right' )
$margins = 'margin: 0px 0px 0px 10px';
- }
-
+ }
+
if ( $cb === false && !$inline ) {
if ( self::$scripts === false )
self::$scripts = array();
-
+
$data = array( 'url' => $poll_js );
-
+
self::$scripts['poll'][] = $data;
-
+
add_action( 'wp_footer', array( $this, 'generate_scripts' ) );
-
+
$data = esc_attr( json_encode( $data ) );
-
+
return <<<CONTAINER
<a id="pd_a_{$poll}"></a>
<div class="PDS_Poll" id="PDI_container{$poll}" data-settings="{$data}" style="display:inline-block;{$float}{$margins}"></div>
@@ -202,7 +202,7 @@ CONTAINER;
else {
if ( $inline )
$cb = '';
-
+
return <<<CONTAINER
<a id="pd_a_{$poll}"></a>
<div class="PDS_Poll" id="PDI_container{$poll}" style="display:inline-block;{$float}{$margins}"></div>
@@ -210,60 +210,60 @@ CONTAINER;
<script type="text/javascript" charset="UTF-8" src="{$poll_js}{$cb}"></script>
<noscript>{$poll_link}</noscript>
CONTAINER;
- }
- }
+ }
+ }
}
}
elseif ( !empty( $survey ) ) { //survey embed
-
+
if ( in_array( $type, array( 'iframe', 'button', 'banner', 'slider' ) ) ) {
-
+
if ( empty( $title ) ) {
$title = 'Take Our Survey';
if( !empty( $link_text ) )
$title = $link_text;
}
-
+
$survey = preg_replace( '/[^a-f0-9]/i', '', $survey );
- $survey_url = esc_url( "http://polldaddy.com/s/{$survey}" );
- $survey_link = sprintf( '<a href="%s">%s</a>', $survey_url, esc_html( $title ) );
-
+ $survey_url = esc_url( "http://polldaddy.com/s/{$survey}" );
+ $survey_link = sprintf( '<a href="%s">%s</a>', $survey_url, esc_html( $title ) );
+
if ( $no_script || $inline || $infinite_scroll )
- return $survey_link;
-
- if ( $type == 'iframe' ) {
+ return $survey_link;
+
+ if ( $type == 'iframe' ) {
if ( $height != 'auto' ) {
- if ( isset( $content_width ) && is_numeric( $width ) && $width > $content_width )
+ if ( isset( $content_width ) && is_numeric( $width ) && $width > $content_width )
$width = $content_width;
-
+
if ( !$width )
$width = '100%';
else
$width = (int) $width;
-
+
if ( !$height )
$height = '600';
else
- $height = (int) $height;
-
+ $height = (int) $height;
+
return <<<CONTAINER
-<iframe src="{$survey_url}?iframe=1" frameborder="0" width="{$width}" height="{$height}" scrolling="auto" allowtransparency="true" marginheight="0" marginwidth="0">{$survey_link}</iframe>
+<iframe src="{$survey_url}?iframe=1" frameborder="0" width="{$width}" height="{$height}" scrolling="auto" allowtransparency="true" marginheight="0" marginwidth="0">{$survey_link}</iframe>
CONTAINER;
- }
+ }
elseif ( !empty( $domain ) && !empty( $id ) ) {
-
- $auto_src = esc_url( "http://{$domain}.polldaddy.com/s/{$id}" );
+
+ $auto_src = esc_url( "http://{$domain}.polldaddy.com/s/{$id}" );
$auto_src = parse_url( $auto_src );
-
+
if ( !is_array( $auto_src ) || count( $auto_src ) == 0 )
return '<!-- no polldaddy output -->';
-
+
if ( !isset( $auto_src['host'] ) || !isset( $auto_src['path'] ) )
return '<!-- no polldaddy output -->';
-
+
$domain = $auto_src['host'].'/s/';
$id = str_ireplace( '/s/', '', $auto_src['path'] );
-
+
$settings = json_encode( array(
'type' => $type,
'auto' => true,
@@ -271,21 +271,21 @@ CONTAINER;
'id' => $id
) );
}
- }
- else {
+ }
+ else {
$text_color = preg_replace( '/[^a-f0-9]/i', '', $text_color );
$back_color = preg_replace( '/[^a-f0-9]/i', '', $back_color );
-
+
if ( !in_array( $align, array( 'right', 'left', 'top-left', 'top-right', 'middle-left', 'middle-right', 'bottom-left', 'bottom-right' ) ) )
$align = '';
-
+
if ( !in_array( $style, array( 'inline', 'side', 'corner', 'rounded', 'square' ) ) )
$style = '';
-
+
$title = wp_strip_all_tags( $title );
$body = wp_strip_all_tags( $body );
$button = wp_strip_all_tags( $button );
-
+
$settings = json_encode( array_filter( array(
'title' => $title,
'type' => $type,
@@ -296,7 +296,7 @@ CONTAINER;
'align' => $align,
'style' => $style,
'id' => $survey
- ) ) );
+ ) ) );
}
return <<<CONTAINER
<script type="text/javascript" charset="UTF-8" src="http://i0.poll.fm/survey.js"></script>
@@ -305,15 +305,15 @@ polldaddy.add( {$settings} );
//--><!]]></script>
<noscript>{$survey_link}</noscript>
CONTAINER;
- }
+ }
}
else
return '<!-- no polldaddy output -->';
}
-
+
function generate_scripts() {
$script = '';
-
+
if ( is_array( self::$scripts ) ) {
if ( isset( self::$scripts['rating'] ) ) {
$script = "<script type='text/javascript' charset='UTF-8' id='polldaddyRatings'><!--//--><![CDATA[//><!--\n";
@@ -321,16 +321,16 @@ CONTAINER;
$script .= "PDRTJS_settings_{$rating['id']}{$rating['item_id']}={$rating['settings']}; if ( typeof PDRTJS_RATING !== 'undefined' ){if ( typeof PDRTJS_{$rating['id']}{$rating['item_id']} == 'undefined' ){PDRTJS_{$rating['id']}{$rating['item_id']} = new PDRTJS_RATING( PDRTJS_settings_{$rating['id']}{$rating['item_id']} );}}";
}
$script .= "\n//--><!]]></script><script type='text/javascript' charset='UTF-8' src='http://i.polldaddy.com/ratings/rating.js'></script>";
-
+
}
-
+
if ( isset( self::$scripts['poll'] ) ) {
foreach( self::$scripts['poll'] as $poll ) {
$script .= "<script type='text/javascript' charset='UTF-8' src='{$poll['url']}'></script>";
}
}
}
-
+
self::$scripts = false;
echo $script;
}
@@ -365,8 +365,8 @@ CONTAINER;
wp_pd_js.type = 'text/javascript';
wp_pd_js.src = $script_url;
wp_pd_js.async = true;
- wp_pd_js.onload = function() {
- jQuery( document.body ).trigger( 'pd-script-load' );
+ wp_pd_js.onload = function() {
+ jQuery( document.body ).trigger( 'pd-script-load' );
};
document.getElementsByTagName( 'head' )[0].appendChild( wp_pd_js );
} else {
@@ -375,7 +375,7 @@ CONTAINER;
//]]>
</script>
SCRIPT;
-
+
}
}
}
@@ -388,7 +388,7 @@ if ( !function_exists( 'polldaddy_link' ) ) {
function polldaddy_link( $content ) {
return preg_replace( '!(?:\n|\A)http://polldaddy.com/poll/([0-9]+?)/(.+)?(?:\n|\Z)!i', "\n<script type='text/javascript' language='javascript' charset='utf-8' src='http://static.polldaddy.com/p/$1.js'></script><noscript> <a href='http://polldaddy.com/poll/$1/'>View Poll</a></noscript>\n", $content );
}
-
+
// higher priority because we need it before auto-link and autop get to it
add_filter( 'the_content', 'polldaddy_link', 1 );
add_filter( 'the_content_rss', 'polldaddy_link', 1 );
diff --git a/plugins/jetpack/modules/shortcodes/slideshare.php b/plugins/jetpack/modules/shortcodes/slideshare.php
index 012b9c7b..97d9d446 100644
--- a/plugins/jetpack/modules/shortcodes/slideshare.php
+++ b/plugins/jetpack/modules/shortcodes/slideshare.php
@@ -1,8 +1,8 @@
<?php
/*
- * Slideshare shortcode format:
+ * Slideshare shortcode format:
* [slideshare id=5342235&doc=camprock-101002163655-phpapp01&w=300&h=200]
- **/
+ **/
function slideshare_shortcode( $atts ) {
global $content_width;
diff --git a/plugins/jetpack/modules/shortcodes/slideshow.php b/plugins/jetpack/modules/shortcodes/slideshow.php
index ab1145d8..f57802b1 100644
--- a/plugins/jetpack/modules/shortcodes/slideshow.php
+++ b/plugins/jetpack/modules/shortcodes/slideshow.php
@@ -102,7 +102,7 @@ class Jetpack_Slideshow_Shortcode {
foreach ( $attachments as $attachment ) {
$attachment_image_src = wp_get_attachment_image_src( $attachment->ID, 'full' );
$attachment_image_src = $attachment_image_src[0]; // [url, width, height]
- $caption = wptexturize( strip_tags( $attachment->post_excerpt ) );
+ $caption = apply_filters( 'jetpack_slideshow_slide_caption', wptexturize( strip_tags( $attachment->post_excerpt ) ), $attachment->ID );
$gallery[] = (object) array(
'src' => (string) esc_url_raw( $attachment_image_src ),
diff --git a/plugins/jetpack/modules/shortcodes/ted.php b/plugins/jetpack/modules/shortcodes/ted.php
index afd35961..4edc2882 100644
--- a/plugins/jetpack/modules/shortcodes/ted.php
+++ b/plugins/jetpack/modules/shortcodes/ted.php
@@ -13,6 +13,10 @@
wp_oembed_add_provider( '!https?://(www\.)?ted.com/talks/view/id/.+!i', 'http://www.ted.com/talks/oembed.json', true );
wp_oembed_add_provider( '!https?://(www\.)?ted.com/talks/[a-zA-Z\-\_]+\.html!i', 'http://www.ted.com/talks/oembed.json', true );
+function jetpack_shortcode_get_ted_id( $atts ) {
+ return ( ! empty( $atts['id'] ) ? $atts['id'] : 0 );
+}
+
add_shortcode( 'ted', 'shortcode_ted' );
function shortcode_ted( $atts, $content = '' ) {
global $wp_embed;
diff --git a/plugins/jetpack/modules/shortcodes/videopress.php b/plugins/jetpack/modules/shortcodes/videopress.php
index 6aebae03..6a3a75b0 100644
--- a/plugins/jetpack/modules/shortcodes/videopress.php
+++ b/plugins/jetpack/modules/shortcodes/videopress.php
@@ -8,7 +8,7 @@
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
-/*
+/*
Plugin Name: VideoPress
Plugin URI: http://wordpress.org/extend/plugins/video/
Description: Upload new videos to <a href="http://videopress.com/">VideoPress</a>, edit metadata, and easily insert VideoPress videos into posts and pages using shortcodes. Requires a <a href="http://wordpress.com/">WordPress.com</a> account and a WordPress.com blog with the <a href="http://en.wordpress.com/products/#videopress">VideoPress upgrade</a> to store and serve uploaded videos.
@@ -113,7 +113,7 @@ class VideoPress {
public static function find_all_shortcodes( $content ) {
$r = preg_match_all( '/(.?)\[(wpvideo|videopress)\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)/s', $content, $matches, PREG_SET_ORDER );
- if ( $r === false || $r === 0 )
+ if ( $r === false || $r === 0 )
return array();
$guids = array();
@@ -187,11 +187,11 @@ class VideoPress {
wp_enqueue_script( 'swfobject', $swfobject, false. '2.2' );
wp_enqueue_script( 'jquery', $jquery, false, '1.4.4' );
wp_enqueue_script( 'videopress', $vpjs, array( 'jquery','swfobject' ), '1.09' );
-
+
$this->js_loaded = true;
return true;
}
-
+
/**
* Print the VideoPress JS files now.
* Used to load the JS in the footer, if it hasn't already been loaded in the header.
@@ -218,7 +218,7 @@ class VideoPress {
$guid = $attr[0];
if ( ! self::is_valid_guid( $guid ) )
return '';
-
+
if ( array_key_exists( $guid, $this->shown ) )
$this->shown[$guid]++;
else
@@ -238,7 +238,7 @@ class VideoPress {
*/
if ( $freedom === false && (bool) get_option( 'video_player_freedom', false ) )
$freedom = true;
-
+
$forcestatic = get_option( 'video_player_static', false );
/**
@@ -360,7 +360,7 @@ class VideoPress_Video {
*
* @var int
* @since 1.3
- */
+ */
public $calculated_height;
/**
@@ -787,7 +787,7 @@ class VideoPress_Player {
public function asXML() {
if ( empty( $this->video ) || is_wp_error( $this->video ) )
return '';
-
+
if ( isset( $this->options['freedom'] ) && $this->options['freedom'] === true )
$content = $this->html5_static();
else
@@ -883,7 +883,7 @@ class VideoPress_Player {
* @link https://developer.mozilla.org/en/JavaScript/Reference/global_objects/date Mozilla JavaScript Reference: Date
*/
$html .= '<select name="month" style="' . $inputs_style . '">';
-
+
$months = array( __('January', 'jetpack'), __('February', 'jetpack'), __('March', 'jetpack'), __('April', 'jetpack'), __('May', 'jetpack'), __('June', 'jetpack'), __('July', 'jetpack'), __('August', 'jetpack'), __('September', 'jetpack'), __('October', 'jetpack'), __('November', 'jetpack'), __('December', 'jetpack') );
for( $i=0; $i<12; $i++ ) {
$html .= '<option value="' . esc_attr( $i ) . '">' . esc_html( $months[$i] ) . '</option>';
diff --git a/plugins/jetpack/modules/shortcodes/vimeo.php b/plugins/jetpack/modules/shortcodes/vimeo.php
index 02b417e1..188c8e2f 100644
--- a/plugins/jetpack/modules/shortcodes/vimeo.php
+++ b/plugins/jetpack/modules/shortcodes/vimeo.php
@@ -9,6 +9,20 @@
<iframe src="http://player.vimeo.com/video/18427511" width="400" height="225" frameborder="0"></iframe><p><a href="http://vimeo.com/18427511">Eskmo 'We Got More' (Official Video)</a> from <a href="http://vimeo.com/ninjatune">Ninja Tune</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
*/
+function jetpack_shortcode_get_vimeo_id( $atts ) {
+ if ( isset( $atts[0] ) ) {
+ $atts[0] = trim( $atts[0] , '=' );
+ if ( is_numeric( $atts[0] ) )
+ $id = (int) $atts[0];
+ elseif ( preg_match( '|vimeo\.com/(\d+)/?$|i', $atts[0], $match ) )
+ $id = (int) $match[1];
+ elseif ( preg_match( '|player\.vimeo\.com/video/(\d+)/?$|i', $atts[0], $match ) )
+ $id = (int) $match[1];
+ return $id;
+ }
+ return 0;
+}
+
/**
* Convert a Vimeo shortcode into an embed code.
*
@@ -24,13 +38,10 @@ function vimeo_shortcode( $atts ) {
'height' => 300
), $atts ) ) );
- if ( isset( $atts[0] ) ) {
- $atts[0] = trim( $atts[0] , '=' );
- if ( is_numeric( $atts[0] ) )
- $id = (int) $atts[0];
- elseif ( preg_match( '|vimeo\.com/(\d+)/?$|i', $atts[0], $match ) )
- $id = (int) $match[1];
- }
+ if ( isset( $atts[0] ) )
+ $id = jetpack_shortcode_get_vimeo_id( $atts );
+
+ if ( ! $id ) return "<!-- vimeo error: not a vimeo video -->";
// [vimeo 141358 h=500&w=350]
$params = shortcode_new_to_old_params( $atts ); // h=500&w=350
@@ -61,8 +72,6 @@ function vimeo_shortcode( $atts ) {
if ( ! $height )
$height = round( ( $width / 640 ) * 360 );
- if ( ! $id ) return "<!-- vimeo error: not a vimeo video -->";
-
$html = "<div class='embed-vimeo' style='text-align:center;'><iframe src='http://player.vimeo.com/video/$id' width='$width' height='$height' frameborder='0'></iframe></div>";
$html = apply_filters( 'video_embed_html', $html );
return $html;
diff --git a/plugins/jetpack/modules/shortcodes/youtube.php b/plugins/jetpack/modules/shortcodes/youtube.php
index 74c497ed..df50af14 100644
--- a/plugins/jetpack/modules/shortcodes/youtube.php
+++ b/plugins/jetpack/modules/shortcodes/youtube.php
@@ -41,6 +41,11 @@ function youtube_embed_to_short_code( $content ) {
$ifr_regexp = '!<iframe((?:\s+\w+="[^"]*")*?)\s+src="https?://(?:www\.)*youtube.com/embed/([^"]+)".*?</iframe>!i';
$ifr_regexp_ent = str_replace( '&amp;#0*58;', '&amp;#0*58;|&#0*58;', htmlspecialchars( $ifr_regexp, ENT_NOQUOTES ) );
+ if ( is_ssl() )
+ $protocol = 'https';
+ else
+ $protocol = 'http';
+
foreach ( array( 'regexp', 'regexp_ent', 'old_regexp', 'old_regexp_ent', 'ifr_regexp', 'ifr_regexp_ent' ) as $reg ) {
if ( ! preg_match_all( $$reg, $content, $matches, PREG_SET_ORDER ) )
continue;
@@ -69,11 +74,11 @@ function youtube_embed_to_short_code( $content ) {
if ( $width && $height )
$wh = "&w=$width&h=$height";
- $url = esc_url_raw( "http://www.youtube.com/watch?v={$match[2]}{$wh}" );
+ $url = esc_url_raw( "$protocol://www.youtube.com/watch?v={$match[2]}{$wh}" );
} else {
$match[1] = str_replace( '?', '&', $match[1] );
- $url = esc_url_raw( 'http://www.youtube.com/watch?v=' . html_entity_decode( $match[1] ) );
+ $url = esc_url_raw( "$protocol://www.youtube.com/watch?v=" . html_entity_decode( $match[1] ) );
}
$content = str_replace( $match[0], "[youtube $url]", $content );
@@ -94,7 +99,7 @@ add_filter('pre_kses', 'youtube_embed_to_short_code');
* @return string The content with embeds instead of URLs
*/
function youtube_link( $content ) {
- return preg_replace_callback( '!(?:\n|\A)http://(?:www\.)?(?:youtube.com/(?:v/|playlist|watch[/\#?])|youtu\.be/)[^\s]+?(?:\n|\Z)!i', 'youtube_link_callback', $content );
+ return preg_replace_callback( '!(?:\n|\A)https?://(?:www\.)?(?:youtube.com/(?:v/|playlist|watch[/\#?])|youtu\.be/)[^\s]+?(?:\n|\Z)!i', 'youtube_link_callback', $content );
}
/**
@@ -137,7 +142,23 @@ function youtube_sanitize_url( $url ) {
* http://youtu.be/Rrohlqeir5E
*/
+/**
+ * Same as get_youtube_id(), but with the prefix that function should've had.
+ */
+function jetpack_shortcode_get_youtube_id( $url ) {
+ return get_youtube_id( $url );
+}
+
+/**
+ * @param $url Can be just the $url or the whole $atts array
+ * @return bool|mixed The Youtube video ID
+ */
function get_youtube_id( $url ) {
+
+ // Do we have an $atts array? Get first att
+ if ( is_array( $url ) )
+ $url = $url[0];
+
$url = youtube_sanitize_url( $url );
$url = parse_url( $url );
$id = false;
@@ -225,10 +246,15 @@ function youtube_id( $url ) {
$fmt = ( isset( $qargs['fmt'] ) && intval( $qargs['fmt'] ) ) ? '&fmt=' . (int) $qargs['fmt'] : '';
$start = ( isset( $qargs['start'] ) && intval( $qargs['start'] ) ) ? '&start=' . (int) $qargs['start'] : '';
+ $end = ( isset( $qargs['end'] ) && intval( $qargs['end'] ) ) ? '&end=' . (int) $qargs['end'] : '';
$hd = ( isset( $qargs['hd'] ) && intval( $qargs['hd'] ) ) ? '&hd=' . (int) $qargs['hd'] : '';
$wmode = ( isset( $qargs['wmode'] ) && in_array( strtolower( $qargs['wmode'] ), array( 'opaque', 'window', 'transparent' ) ) ) ? $qargs['wmode'] : 'transparent';
+ $autoplay = '';
+ if ( apply_filters( 'jetpack_youtube_allow_autoplay', false ) && isset( $qargs['autoplay'] ) )
+ $autoplay = '&autoplay=' . (int)$qargs['autoplay'];
+
$alignmentcss = 'text-align:center;';
if ( isset( $qargs['align'] ) ) {
switch ( $qargs['align'] ) {
@@ -241,10 +267,15 @@ function youtube_id( $url ) {
}
}
+ if ( is_ssl() )
+ $protocol = 'https';
+ else
+ $protocol = 'http';
+
if ( ( isset( $url['path'] ) && '/videoseries' == $url['path'] ) || isset( $qargs['list'] ) ) {
- $html = "<span class='embed-youtube' style='$alignmentcss display: block;'><iframe class='youtube-player' type='text/html' width='$w' height='$h' src='" . esc_url( "http://www.youtube.com/embed/videoseries?list=$id&hl=en_US" ) . "' frameborder='0'></iframe></span>";
+ $html = "<span class='embed-youtube' style='$alignmentcss display: block;'><iframe class='youtube-player' type='text/html' width='$w' height='$h' src='" . esc_url( "$protocol://www.youtube.com/embed/videoseries?list=$id&hl=en_US" ) . "' frameborder='0'></iframe></span>";
} else {
- $html = "<span class='embed-youtube' style='$alignmentcss display: block;'><iframe class='youtube-player' type='text/html' width='$w' height='$h' src='" . esc_url( "http://www.youtube.com/embed/$id?version=3&rel=$rel&fs=1$fmt&showsearch=$search&showinfo=$info&iv_load_policy=$iv$start$hd&wmode=$wmode" ) . "' frameborder='0'></iframe></span>";
+ $html = "<span class='embed-youtube' style='$alignmentcss display: block;'><iframe class='youtube-player' type='text/html' width='$w' height='$h' src='" . esc_url( "$protocol://www.youtube.com/embed/$id?version=3&rel=$rel&fs=1$fmt&showsearch=$search&showinfo=$info&iv_load_policy=$iv$start$end$hd&wmode=$wmode$autoplay" ) . "' frameborder='0'></iframe></span>";
}
$html = apply_filters( 'video_embed_html', $html );
@@ -267,7 +298,7 @@ function wpcom_youtube_embed_crazy_url( $matches, $attr, $url ) {
}
function wpcom_youtube_embed_crazy_url_init() {
- wp_embed_register_handler( 'wpcom_youtube_embed_crazy_url', '#http://(?:www\.)?(?:youtube.com/(?:v/|playlist|watch[/\#?])|youtu\.be/).*#i', 'wpcom_youtube_embed_crazy_url' );
+ wp_embed_register_handler( 'wpcom_youtube_embed_crazy_url', '#https?://(?:www\.)?(?:youtube.com/(?:v/|playlist|watch[/\#?])|youtu\.be/).*#i', 'wpcom_youtube_embed_crazy_url' );
}
add_action( 'init', 'wpcom_youtube_embed_crazy_url_init' );
diff --git a/plugins/jetpack/modules/shortlinks.php b/plugins/jetpack/modules/shortlinks.php
index 98ec743d..731a5c3a 100644
--- a/plugins/jetpack/modules/shortlinks.php
+++ b/plugins/jetpack/modules/shortlinks.php
@@ -4,6 +4,7 @@
* Module Description: Enable WP.me-powered shortlinks for all of your Posts and Pages for easier sharing.
* Sort Order: 10
* First Introduced: 1.1
+ * Requires Connection: Yes
*/
add_filter( 'get_shortlink', 'wpme_get_shortlink_handler', 1, 4 );
diff --git a/plugins/jetpack/modules/stats.php b/plugins/jetpack/modules/stats.php
index 260b3f58..3ca38ddb 100644
--- a/plugins/jetpack/modules/stats.php
+++ b/plugins/jetpack/modules/stats.php
@@ -4,13 +4,14 @@
* Module Description: Simple, concise site stats with no additional load on your server.
* Sort Order: 1
* First Introduced: 1.1
+ * Requires Connection: Yes
*/
if ( defined( 'STATS_VERSION' ) ) {
return;
}
-define( 'STATS_VERSION', '8' );
+define( 'STATS_VERSION', '9' );
defined( 'STATS_DASHBOARD_SERVER' ) or define( 'STATS_DASHBOARD_SERVER', 'dashboard.wordpress.com' );
add_action( 'jetpack_modules_loaded', 'stats_load' );
@@ -51,6 +52,8 @@ function stats_load() {
add_action( 'wp_head', 'stats_admin_bar_head', 100 );
+ add_action( 'wp_head', 'stats_hide_smile_css' );
+
add_action( 'jetpack_admin_menu', 'stats_admin_menu' );
add_action( 'wp_dashboard_setup', 'stats_register_dashboard_widget' );
@@ -85,7 +88,6 @@ function stats_ignore_db_version( $version ) {
* @return array Possibly mapped capabilities for meta capability
*/
function stats_map_meta_caps( $caps, $cap, $user_id, $args ) {
-
// Map view_stats to exists
if ( 'view_stats' == $cap ) {
$user = new WP_User( $user_id );
@@ -108,11 +110,13 @@ function stats_template_redirect() {
return;
$options = stats_get_options();
- // Ensure this is always setup for the check below
- $options['reg_users'] = empty( $options['reg_users'] ) ? false : true;
- if ( !$options['reg_users'] && !empty( $current_user->ID ) )
- return;
+ // Should we be counting this user's views?
+ if ( !empty( $current_user->ID ) ) {
+ $count_roles = stats_get_option( 'count_roles' );
+ if ( ! array_intersect( $current_user->roles, $count_roles ) )
+ return;
+ }
add_action( 'wp_footer', 'stats_footer', 101 );
add_action( 'wp_head', 'stats_add_shutdown_action' );
@@ -154,9 +158,6 @@ function stats_template_redirect() {
else load_cmc();
</script>
END;
- if ( isset( $options['hide_smile'] ) && $options['hide_smile'] ) {
- $stats_footer .= "\n<style type='text/css'>img#wpstats{display:none}</style>";
- }
}
function stats_add_shutdown_action() {
@@ -207,11 +208,20 @@ function stats_upgrade_options( $options ) {
$defaults = array(
'admin_bar' => true,
'roles' => array( 'administrator' ),
+ 'count_roles' => array(),
'blog_id' => Jetpack::get_option( 'id' ),
'do_not_track' => true, // @todo
'hide_smile' => false,
);
+ if ( isset( $options['reg_users'] ) ) {
+ if ( ! function_exists( 'get_editable_roles' ) )
+ require_once( ABSPATH . 'wp-admin/includes/user.php' );
+ if ( $options['reg_users'] )
+ $options['count_roles'] = array_keys( get_editable_roles() );
+ unset( $options['reg_users'] );
+ }
+
if ( is_array( $options ) && !empty( $options ) )
$new_options = array_merge( $defaults, $options );
else
@@ -447,7 +457,7 @@ function stats_convert_image_urls( $html ) {
}
function stats_convert_chart_urls( $html ) {
- $html = preg_replace_callback( '|https?://[-.a-z0-9]+/wp-includes/charts/([-.a-z0-9]+).php(\??)|',
+ $html = preg_replace_callback( '|https?://[-.a-z0-9]+/wp-includes/charts/([-.a-z0-9]+).php(\??)|',
create_function(
'$matches',
// If there is a query string, change the beginning '?' to a '&' so it fits into the middle of this query string
@@ -486,7 +496,6 @@ function stats_configuration_load() {
if ( isset( $_POST['action'] ) && $_POST['action'] == 'save_options' && $_POST['_wpnonce'] == wp_create_nonce( 'stats' ) ) {
$options = stats_get_options();
$options['admin_bar'] = isset( $_POST['admin_bar'] ) && $_POST['admin_bar'];
- $options['reg_users'] = isset( $_POST['reg_users'] ) && $_POST['reg_users'];
$options['hide_smile'] = isset( $_POST['hide_smile'] ) && $_POST['hide_smile'];
$options['roles'] = array( 'administrator' );
@@ -494,6 +503,11 @@ function stats_configuration_load() {
if ( isset( $_POST["role_$role"] ) && $_POST["role_$role"] )
$options['roles'][] = $role;
+ $options['count_roles'] = array();
+ foreach ( get_editable_roles() as $role => $details )
+ if ( isset( $_POST["count_role_$role"] ) && $_POST["count_role_$role"] )
+ $options['count_roles'][] = $role;
+
stats_set_options( $options );
stats_update_blog();
Jetpack::state( 'message', 'module_configured' );
@@ -519,7 +533,6 @@ function stats_configuration_head() {
function stats_configuration_screen() {
$options = stats_get_options();
- $options['reg_users'] = empty( $options['reg_users'] ) ? false : true;
?>
<div class="narrow">
<p><?php printf( __( 'Visit <a href="%s">Site Stats</a> to see your stats.', 'jetpack' ), esc_url( menu_page_url( 'stats', false ) ) ); ?></p>
@@ -529,8 +542,18 @@ function stats_configuration_screen() {
<table id="menu" class="form-table">
<tr valign="top"><th scope="row"><label for="admin_bar"><?php _e( 'Admin bar' , 'jetpack' ); ?></label></th>
<td><label><input type='checkbox'<?php checked( $options['admin_bar'] ); ?> name='admin_bar' id='admin_bar' /> <?php _e( "Put a chart showing 48 hours of views in the admin bar.", 'jetpack' ); ?></label></td></tr>
- <tr valign="top"><th scope="row"><label for="reg_users"><?php _e( 'Registered users', 'jetpack' ); ?></label></th>
- <td><label><input type='checkbox'<?php checked( $options['reg_users'] ); ?> name='reg_users' id='reg_users' /> <?php _e( "Count the page views of registered users who are logged in.", 'jetpack' ); ?></label></td></tr>
+ <tr valign="top"><th scope="row"><?php _e( 'Registered users', 'jetpack' ); ?></th>
+ <td>
+ <?php _e( "Count the page views of registered users who are logged in.", 'jetpack' ); ?><br/>
+ <?php
+ $count_roles = stats_get_option( 'count_roles' );
+ foreach ( get_editable_roles() as $role => $details ) {
+ ?>
+ <label><input type='checkbox' name='count_role_<?php echo $role; ?>'<?php checked( in_array( $role, $count_roles ) ); ?> /> <?php echo translate_user_role( $details['name'] ); ?></label><br/>
+ <?php
+ }
+ ?>
+ </td></tr>
<tr valign="top"><th scope="row"><?php _e( 'Smiley' , 'jetpack' ); ?></th>
<td><label><input type='checkbox'<?php checked( isset( $options['hide_smile'] ) && $options['hide_smile'] ); ?> name='hide_smile' id='hide_smile' /> <?php _e( 'Hide the stats smiley face image.', 'jetpack' ); ?></label><br /> <span class="description"><?php _e( 'The image helps collect stats and <strong>makes the world a better place</strong> but should still work when hidden', 'jetpack' ); ?> <img class="stats-smiley" alt="<?php esc_attr_e( 'Smiley face', 'jetpack' ); ?>" src="<?php echo esc_url( plugins_url( '_inc/images/stats-smiley.gif', dirname( __FILE__ ) ) ); ?>" width="6" height="5" /></span></td></tr>
<tr valign="top"><th scope="row"><?php _e( 'Report visibility' , 'jetpack' ); ?></th>
@@ -544,7 +567,7 @@ function stats_configuration_screen() {
<?php
}
?>
- </tr>
+ </td></tr>
</table>
<p class="submit"><input type='submit' class='button-primary' value='<?php echo esc_attr( __( 'Save configuration', 'jetpack' ) ); ?>' /></p>
</form>
@@ -552,6 +575,14 @@ function stats_configuration_screen() {
<?php
}
+function stats_hide_smile_css() {
+ $options = stats_get_options();
+ if ( isset( $options['hide_smile'] ) && $options['hide_smile'] ) {
+ ?>
+<style type='text/css'>img#wpstats{display:none}</style><?php
+ }
+}
+
function stats_admin_bar_head() {
if ( !stats_get_option( 'admin_bar' ) )
return;
@@ -889,15 +920,23 @@ function stats_dashboard_widget_content() {
/* translators: Stats dashboard widget postviews list: "$post_title $views Views" */
$printf = __( '%1$s %2$s Views' , 'jetpack' );
- foreach ( $top_posts = stats_get_csv( 'postviews', "days=$options[top]$csv_args[top]" ) as $post )
+ foreach ( $top_posts = stats_get_csv( 'postviews', "days=$options[top]$csv_args[top]" ) as $i => $post ) {
+ if ( $post['post_id'] == 0 ) {
+ unset( $top_posts[$i] );
+ continue;
+ }
$post_ids[] = $post['post_id'];
+ }
// cache
get_posts( array( 'include' => join( ',', array_unique( $post_ids ) ) ) );
$searches = array();
- foreach ( $search_terms = stats_get_csv( 'searchterms', "days=$options[search]$csv_args[search]" ) as $search_term )
+ foreach ( $search_terms = stats_get_csv( 'searchterms', "days=$options[search]$csv_args[search]" ) as $search_term ) {
+ if ( $search_term['searchterm'] == 'encrypted_search_terms' )
+ continue;
$searches[] = esc_html( $search_term['searchterm'] );
+ }
?>
<a class="button" href="admin.php?page=stats"><?php _e( 'View All', 'jetpack' ); ?></a>
diff --git a/plugins/jetpack/modules/subscriptions.php b/plugins/jetpack/modules/subscriptions.php
index 39c639ff..22366d07 100644
--- a/plugins/jetpack/modules/subscriptions.php
+++ b/plugins/jetpack/modules/subscriptions.php
@@ -4,10 +4,11 @@
* Module Description: Allow users to subscribe to your posts and comments to receive a notification via email.
* Sort Order: 3
* First Introduced: 1.2
+ * Requires Connection: Yes
*/
add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
-
+
Jetpack_Sync::sync_options( __FILE__,
'home',
'blogname',
@@ -42,7 +43,7 @@ class Jetpack_Subscriptions {
* Singleton
* @static
*/
- function init() {
+ static function init() {
static $instance = false;
if ( !$instance ) {
@@ -101,7 +102,7 @@ class Jetpack_Subscriptions {
*
* Jetpack Subscriptions configuration screen.
*/
- function configure() {
+ function configure() {
// Create the section
add_settings_section(
'jetpack_subscriptions',
@@ -139,37 +140,37 @@ class Jetpack_Subscriptions {
'discussion',
'stc_enabled'
);
-
+
/** Subscription Messaging Options ******************************************************/
-
- register_setting(
- 'reading',
- 'subscription_options',
- array( $this, 'validate_settings' )
+
+ register_setting(
+ 'reading',
+ 'subscription_options',
+ array( $this, 'validate_settings' )
);
- add_settings_section(
- 'email_settings',
- __( 'Follower Settings', 'jetpack' ),
- array( $this, 'reading_section' ),
+ add_settings_section(
+ 'email_settings',
+ __( 'Follower Settings', 'jetpack' ),
+ array( $this, 'reading_section' ),
'reading'
);
-
+
add_settings_field(
'invitation',
- __( 'Blog follow email text' , 'jetpack' ),
- array( $this, 'setting_invitation' ),
- 'reading',
+ __( 'Blog follow email text' , 'jetpack' ),
+ array( $this, 'setting_invitation' ),
+ 'reading',
'email_settings'
);
add_settings_field(
'comment-follow',
- __( 'Comment follow email text', 'jetpack' ),
- array( $this, 'setting_comment_follow' ),
- 'reading',
+ __( 'Comment follow email text', 'jetpack' ),
+ array( $this, 'setting_comment_follow' ),
+ 'reading',
'email_settings'
- );
+ );
}
/**
@@ -255,11 +256,11 @@ class Jetpack_Subscriptions {
'comment_follow' => __( "Howdy.\n\nYou recently followed one of my posts. This means you will receive an email when new comments are posted.\n\nTo activate, click confirm below. If you believe this is an error, ignore this message and we'll never bother you again." , 'jetpack')
);
}
-
+
function get_settings() {
return wp_parse_args( (array) get_option( 'subscription_options', array() ), $this->get_default_settings() );
}
-
+
/**
* Jetpack_Subscriptions::subscribe()
*
@@ -658,7 +659,7 @@ class Jetpack_Subscriptions_Widget extends WP_Widget {
return $instance;
}
- function defaults() {
+ public static function defaults() {
return array(
'title' => esc_html__( 'Subscribe to Blog via Email', 'jetpack' ),
'subscribe_text' => esc_html__( 'Enter your email address to subscribe to this blog and receive notifications of new posts by email.', 'jetpack' ),
@@ -680,7 +681,7 @@ class Jetpack_Subscriptions_Widget extends WP_Widget {
if ( 'failed' == $subs_fetch['status'] ) {
printf( '<div class="error inline"><p>' . __( '%s: %s', 'jetpack' ) . '</p></div>', esc_html( $subs_fetch['code'] ), esc_html( $subs_fetch['message'] ) );
-
+
}
$subscribers_total = number_format_i18n( $subs_fetch['value'] );
@@ -706,7 +707,7 @@ class Jetpack_Subscriptions_Widget extends WP_Widget {
<p>
<label for="<?php echo $this->get_field_id( 'show_subscribers_total' ); ?>">
<input type="checkbox" id="<?php echo $this->get_field_id( 'show_subscribers_total' ); ?>" name="<?php echo $this->get_field_name( 'show_subscribers_total' ); ?>" value="1"<?php echo $show_subscribers_total; ?> />
- <?php echo esc_html( sprintf( _n( 'Show total number of subscribers? (%s subscriber)', 'Show total number of subscribers? (%s subscribers)', $subscribers_total, 'jetpack' ), number_format_i18n( $subscribers_total ) ) ); ?>
+ <?php echo esc_html( sprintf( _n( 'Show total number of subscribers? (%s subscriber)', 'Show total number of subscribers? (%s subscribers)', $subscribers_total, 'jetpack' ), $subscribers_total ) ); ?>
</label>
</p>
<?php
diff --git a/plugins/jetpack/modules/tiled-gallery.php b/plugins/jetpack/modules/tiled-gallery.php
index 6db87144..f88cc680 100644
--- a/plugins/jetpack/modules/tiled-gallery.php
+++ b/plugins/jetpack/modules/tiled-gallery.php
@@ -4,6 +4,7 @@
* Module Name: Tiled Galleries
* Module Description: Create elegant magazine-style mosaic layouts for your photos without using an external graphic editor.
* First Introduced: 2.1
+ * Requires Connection: Yes
*/
function jetpack_load_tiled_gallery() {
diff --git a/plugins/jetpack/modules/tiled-gallery/math/class-constrained-array-rounding.php b/plugins/jetpack/modules/tiled-gallery/math/class-constrained-array-rounding.php
index dab5fd27..f2cf2e59 100644
--- a/plugins/jetpack/modules/tiled-gallery/math/class-constrained-array-rounding.php
+++ b/plugins/jetpack/modules/tiled-gallery/math/class-constrained-array-rounding.php
@@ -2,7 +2,7 @@
/**
* Lets you round the numeric elements of an array to integers while preserving their sum.
- *
+ *
* Usage:
*
* Jetpack_Constrained_Array_Rounding::get_rounded_constrained_array( $bound_array )
@@ -20,14 +20,14 @@ class Jetpack_Constrained_Array_Rounding {
$bound_array = array_values( $bound_array );
$bound_array_int = self::get_int_floor_array( $bound_array );
-
+
$lower_sum = array_sum( wp_list_pluck( $bound_array_int, 'floor' ) );
if ( ! $sum || ( $sum < $lower_sum ) ) {
// If value of sum is not supplied or is invalid, calculate the sum that the returned array is constrained to match
$sum = array_sum( $bound_array );
}
$diff_sum = $sum - $lower_sum;
-
+
self::adjust_constrained_array( $bound_array_int, $diff_sum );
$bound_array_fin = wp_list_pluck( $bound_array_int, 'floor' );
diff --git a/plugins/jetpack/modules/tiled-gallery/tiled-gallery.php b/plugins/jetpack/modules/tiled-gallery/tiled-gallery.php
index 342e8a65..7855da83 100644
--- a/plugins/jetpack/modules/tiled-gallery/tiled-gallery.php
+++ b/plugins/jetpack/modules/tiled-gallery/tiled-gallery.php
@@ -9,6 +9,7 @@ class Jetpack_Tiled_Gallery {
public function __construct() {
add_action( 'admin_init', array( $this, 'settings_api_init' ) );
add_filter( 'jetpack_gallery_types', array( $this, 'jetpack_gallery_types' ), 9 );
+ add_filter( 'jetpack_default_gallery_type', array( $this, 'jetpack_default_gallery_type' ) );
}
public function tiles_enabled() {
@@ -213,7 +214,15 @@ class Jetpack_Tiled_Gallery {
$html = '<div '. $this->gallery_classes() . ' data-original-width="' . esc_attr( self::get_content_width() ) . '">';
$blog_id = (int) get_current_blog_id();
- $extra_data = array( 'data-carousel-extra' => array( 'blog_id' => $blog_id, 'permalink' => get_permalink( $post->ID ) ) );
+
+ if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $likes_blog_id = $blog_id;
+ } else {
+ $jetpack = Jetpack::init();
+ $likes_blog_id = $jetpack->get_option( 'id' );
+ }
+
+ $extra_data = array( 'data-carousel-extra' => array( 'blog_id' => $blog_id, 'permalink' => get_permalink( $post->ID ), 'likes_blog_id' => $likes_blog_id ) );
foreach ( (array) $extra_data as $data_key => $data_values ) {
$html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
@@ -264,7 +273,7 @@ class Jetpack_Tiled_Gallery {
}
public function gallery_classes() {
- $classes = 'class="tiled-gallery type-' . esc_attr( $this->atts['type'] ) . '"';
+ $classes = 'class="tiled-gallery type-' . esc_attr( $this->atts['type'] ) . ' tiled-gallery-unresized"';
return $classes;
}
@@ -283,9 +292,7 @@ class Jetpack_Tiled_Gallery {
}
public static function get_content_width() {
- global $content_width;
-
- $tiled_gallery_content_width = $content_width;
+ $tiled_gallery_content_width = Jetpack::get_content_width();
if ( ! $tiled_gallery_content_width )
$tiled_gallery_content_width = 500;
@@ -297,12 +304,24 @@ class Jetpack_Tiled_Gallery {
* Media UI integration
*/
function jetpack_gallery_types( $types ) {
- $types['rectangular'] = __( 'Tiles', 'jetpack' );
+ if ( get_option( 'tiled_galleries' ) && isset( $types['default'] ) ) {
+ // Tiled is set as the default, meaning that type='default'
+ // will still display the mosaic.
+ $types['thumbnails'] = $types['default'];
+ unset( $types['default'] );
+ }
+
+ $types['rectangular'] = __( 'Tiled Mosaic', 'jetpack' );
$types['square'] = __( 'Square Tiles', 'jetpack' );
$types['circle'] = __( 'Circles', 'jetpack' );
+
return $types;
}
+ function jetpack_default_gallery_type( $default ) {
+ return ( get_option( 'tiled_galleries' ) ? 'rectangular' : 'default' );
+ }
+
/**
* Add a checkbox field to the Carousel section in Settings > Media
* for setting tiled galleries as the default.
@@ -348,8 +367,7 @@ class Jetpack_Tiled_Gallery_Shape {
}
public function is_wide_theme() {
- global $content_width;
- return $content_width > 1000;
+ return Jetpack::get_content_width() > 1000;
}
public static function set_last_shape( $last_shape ) {
diff --git a/plugins/jetpack/modules/tiled-gallery/tiled-gallery/rtl/tiled-gallery-rtl.css b/plugins/jetpack/modules/tiled-gallery/tiled-gallery/rtl/tiled-gallery-rtl.css
index 007c0ccf..a6b7aef0 100644
--- a/plugins/jetpack/modules/tiled-gallery/tiled-gallery/rtl/tiled-gallery-rtl.css
+++ b/plugins/jetpack/modules/tiled-gallery/tiled-gallery/rtl/tiled-gallery-rtl.css
@@ -1,4 +1,4 @@
-/* This file was automatically generated on Jan 05 2013 15:45:53 */
+/* This file was automatically generated on Jul 03 2013 18:11:40 */
/* =Tiled Gallery Default Styles
-------------------------------------------------------------- */
@@ -13,13 +13,13 @@
}
.tiled-gallery .gallery-group {
float: right;
- overflow-y: hidden;
position: relative;
}
.tiled-gallery .tiled-gallery-item {
float: right;
margin: 0;
position: relative;
+ width: inherit; /* prevents ie8 bug with inline width styles */
}
.tiled-gallery .gallery-row {
overflow: hidden;
@@ -62,6 +62,14 @@
font-size: 11px;
}
+/* Hide galleries in widgets until they've been resized to fit.
+ Gallery widgets are almost guaranteed to need resizing, and
+ the jump is a little more obvious than galleries in content. */
+.widget-gallery .tiled-gallery-unresized {
+ visibility: hidden;
+ height: 0px;
+ overflow: hidden;
+}
/* =Greyscale
-------------------------------------------------------------- */
@@ -85,4 +93,5 @@
.tiled-gallery.type-circle .tiled-gallery-caption {
display: none;
opacity: 0;
-} \ No newline at end of file
+}
+
diff --git a/plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.css b/plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.css
index 3a1924df..c80a5b0d 100644
--- a/plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.css
+++ b/plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.css
@@ -17,6 +17,7 @@
float: left;
margin: 0;
position: relative;
+ width: inherit; /* prevents ie8 bug with inline width styles */
}
.tiled-gallery .gallery-row {
overflow: hidden;
@@ -59,6 +60,14 @@
font-size: 11px;
}
+/* Hide galleries in widgets until they've been resized to fit.
+ Gallery widgets are almost guaranteed to need resizing, and
+ the jump is a little more obvious than galleries in content. */
+.widget-gallery .tiled-gallery-unresized {
+ visibility: hidden;
+ height: 0px;
+ overflow: hidden;
+}
/* =Greyscale
-------------------------------------------------------------- */
@@ -82,4 +91,5 @@
.tiled-gallery.type-circle .tiled-gallery-caption {
display: none;
opacity: 0;
-} \ No newline at end of file
+}
+
diff --git a/plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.js b/plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.js
index 90f8ed76..bedb5b52 100644
--- a/plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.js
+++ b/plugins/jetpack/modules/tiled-gallery/tiled-gallery/tiled-gallery.js
@@ -9,13 +9,13 @@ var TiledGallery = function() {
$( window ).on( 'resize', function () {
clearTimeout( self.resizeTimeout );
-
+
self.resizeTimeout = setTimeout( function () { self.resize(); }, 150 );
} );
// Make any new galleries loaded by Infinite Scroll flexible
$( 'body' ).on( 'post-load', $.proxy( self.initialize, self ) );
-
+
// Populate and set up captions on newdash galleries.
$( document ).on( 'page-rendered.wpcom-newdash', $.proxy( self.populate, self ) );
@@ -51,9 +51,10 @@ TiledGallery.prototype.Captions = function() {
/* Hide captions */
this.caption.hide();
- this.item.on( 'hover', function() {
- $( this ).find( '.tiled-gallery-caption' ).slideToggle( 'fast' );
- });
+ this.item.hover(
+ function() { $( this ).find( '.tiled-gallery-caption' ).slideDown( 'fast' ); },
+ function() { $( this ).find( '.tiled-gallery-caption' ).slideUp( 'fast' ); }
+ );
};
TiledGallery.prototype.resize = function() {
@@ -61,7 +62,7 @@ TiledGallery.prototype.resize = function() {
this.gallery.each( function ( galleryIndex, galleryElement ) {
var thisGallery = $( galleryElement );
-
+
// All images must be loaded before proceeding.
var imagesLoaded = true;
@@ -134,6 +135,8 @@ TiledGallery.prototype.resize = function() {
.width( Math.floor( resizeRatio * thisGalleryElement.data( 'original-width' ) ) - thisGalleryElement.data( 'extra-width' ) )
.height( Math.floor( resizeRatio * thisGalleryElement.data( 'original-height' ) ) - thisGalleryElement.data( 'extra-height' ) );
} );
+
+ thisGallery.removeClass( 'tiled-gallery-unresized' );
} );
};
diff --git a/plugins/jetpack/modules/vaultpress.php b/plugins/jetpack/modules/vaultpress.php
index a9b809c2..7766f539 100644
--- a/plugins/jetpack/modules/vaultpress.php
+++ b/plugins/jetpack/modules/vaultpress.php
@@ -1,4 +1,4 @@
-<?php
+<?php
/**
* Module Name: VaultPress
* Module Description: Realtime backup and security scanning for your WordPress site.
@@ -6,6 +6,7 @@
* Sort Order: 7
* Deactivate: false
* Free: false
+ * Requires Connection: Yes
*/
add_action( 'jetpack_modules_loaded', 'vaultpress_jetpack_stub' );
@@ -16,7 +17,7 @@ function vaultpress_jetpack_stub() {
Jetpack::module_configuration_load( __FILE__, 'vaultpress_jetpack_configure' );
add_filter( 'jetpack_module_free_text_vaultpress', 'vaultpress_jetpack_module_free_text' );
}
-}
+}
function vaultpress_jetpack_module_free_text() {
return __( 'Active', 'jetpack' );
diff --git a/plugins/jetpack/modules/widgets.php b/plugins/jetpack/modules/widgets.php
index 5771cdbe..4d0f509d 100644
--- a/plugins/jetpack/modules/widgets.php
+++ b/plugins/jetpack/modules/widgets.php
@@ -4,11 +4,20 @@
* Module Description: Easily add images, Twitter updates, and your site's RSS links to your theme's sidebar.
* Sort Order: 13
* First Introduced: 1.2
+ * Requires Connection: No
*/
function jetpack_load_widgets() {
+ $widgets_include = array();
+
foreach ( Jetpack::glob_php( dirname( __FILE__ ) . '/widgets' ) as $file ) {
- include $file;
+ $widgets_include[] = $file;
+ }
+
+ $widgets_include = apply_filters( 'jetpack_widgets_to_include', $widgets_include );
+
+ foreach( $widgets_include as $include ) {
+ include $include;
}
}
diff --git a/plugins/jetpack/modules/widgets/facebook-likebox.php b/plugins/jetpack/modules/widgets/facebook-likebox.php
index f8ab2512..8cb7e02b 100644
--- a/plugins/jetpack/modules/widgets/facebook-likebox.php
+++ b/plugins/jetpack/modules/widgets/facebook-likebox.php
@@ -37,11 +37,11 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
}
function widget( $args, $instance ) {
-
+
extract( $args );
-
+
$like_args = $this->normalize_facebook_args( $instance['like_args'] );
-
+
if ( empty( $like_args['href'] ) || ! $this->is_valid_facebook_url( $like_args['href'] ) ) {
if ( current_user_can('edit_theme_options') ) {
echo $before_widget;
@@ -51,7 +51,7 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
echo '<!-- Invalid Facebook Page URL -->';
return;
}
-
+
$title = apply_filters( 'widget_title', $instance['title'] );
$page_url = ( is_ssl() ) ? str_replace( 'http://', 'https://', $like_args['href'] ) : $like_args['href'];
@@ -59,16 +59,17 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
$like_args['show_faces'] = (bool) $like_args['show_faces'] ? 'true' : 'false';
$like_args['stream'] = (bool) $like_args['stream'] ? 'true' : 'false';
$like_args['force_wall'] = (bool) $like_args['force_wall'] ? 'true' : 'false';
+ $like_args['show_border']= (bool) $like_args['show_border'] ? 'true' : 'false';
$like_args['header'] = (bool) $like_args['header'] ? 'true' : 'false';
- $like_bg_colour = ( 'dark' == $like_args['colorscheme'] ) ? '#000' : '#fff';
-
+ $like_bg_colour = apply_filters( 'jetpack_fb_likebox_bg', ( 'dark' == $like_args['colorscheme'] ? '#000' : '#fff' ), $like_args['colorscheme'] );
+
$locale = $this->get_locale();
if ( $locale && 'en_US' != $locale )
$like_args['locale'] = $locale;
$like_args = urlencode_deep( $like_args );
$like_url = add_query_arg( $like_args, sprintf( '%swww.facebook.com/plugins/likebox.php', ( is_ssl() ) ? 'https://' : 'http://' ) );
-
+
echo $before_widget;
if ( ! empty( $title ) ) :
@@ -85,13 +86,13 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
}
function update( $new_instance, $old_instance ) {
- $instance = array(
+ $instance = array(
'title' => '',
'like_args' => $this->get_default_args(),
);
$instance['title'] = trim( strip_tags( stripslashes( $new_instance['title'] ) ) );
-
+
// Set up widget values
$instance['like_args'] = array(
'href' => trim( strip_tags( stripslashes( $new_instance['href'] ) ) ),
@@ -100,30 +101,31 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
'colorscheme' => $new_instance['colorscheme'],
'show_faces' => (bool) $new_instance['show_faces'],
'stream' => (bool) $new_instance['stream'],
+ 'show_border' => (bool) $new_instance['show_border'],
'header' => false, // The header just displays "Find us on Facebook"; it's redundant with the title
'force_wall' => (bool) $new_instance['force_wall'],
);
-
+
$instance['like_args'] = $this->normalize_facebook_args( $instance['like_args'] );
return $instance;
}
function form( $instance ) {
- $instance = wp_parse_args( (array) $instance, array(
+ $instance = wp_parse_args( (array) $instance, array(
'title' => '',
'like_args' => $this->get_default_args()
) );
$like_args = $this->normalize_facebook_args( $instance['like_args'] );
?>
-
+
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>">
<?php _e( 'Title', 'jetpack' ); ?>
<input type="text" name="<?php echo $this->get_field_name( 'title' ); ?>" id="<?php echo $this->get_field_id( 'title' ); ?>" value="<?php echo esc_attr( $instance['title'] ); ?>" class="widefat" />
</label>
</p>
-
+
<p>
<label for="<?php echo $this->get_field_id( 'href' ); ?>">
<?php _e( 'Facebook Page URL', 'jetpack' ); ?>
@@ -132,21 +134,21 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
<small><?php _e( 'The Like Box only works with <a href="http://www.facebook.com/help/?faq=174987089221178">Facebook Pages</a>.', 'jetpack' ); ?></small>
</label>
</p>
-
+
<p>
<label for="<?php echo $this->get_field_id( 'width' ); ?>">
<?php _e( 'Width', 'jetpack' ); ?>
- <input type="text" maxlength="3" name="<?php echo $this->get_field_name( 'width' ); ?>" id="<?php echo $this->get_field_id( 'width' ); ?>" value="<?php echo esc_attr( $like_args['width'] ); ?>" style="width: 30px; text-align: center;" />px
+ <input type="number" class="smalltext" min="1" max="999" maxlength="3" name="<?php echo $this->get_field_name( 'width' ); ?>" id="<?php echo $this->get_field_id( 'width' ); ?>" value="<?php echo esc_attr( $like_args['width'] ); ?>" style="text-align: center;" />px
</label>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'height' ); ?>">
<?php _e( 'Height', 'jetpack' ); ?>
- <input type="text" maxlength="3" name="<?php echo $this->get_field_name( 'height' ); ?>" id="<?php echo $this->get_field_id( 'height' ); ?>" value="<?php echo esc_attr( $like_args['height'] ); ?>" style="width: 30px; text-align: center;" />px
+ <input type="number" class="smalltext" min="1" max="999" maxlength="3" name="<?php echo $this->get_field_name( 'height' ); ?>" id="<?php echo $this->get_field_id( 'height' ); ?>" value="<?php echo esc_attr( $like_args['height'] ); ?>" style="text-align: center;" />px
</label>
</p>
-
+
<p>
<label for="<?php echo $this->get_field_id( 'colorscheme' ); ?>">
<?php _e( 'Color Scheme', 'jetpack' ); ?>
@@ -156,8 +158,7 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
</select>
</label>
</p>
-
-
+
<p>
<label for="<?php echo $this->get_field_id( 'show_faces' ); ?>">
<input type="checkbox" name="<?php echo $this->get_field_name( 'show_faces' ); ?>" id="<?php echo $this->get_field_id( 'show_faces' ); ?>" <?php checked( $like_args['show_faces'] ); ?> />
@@ -166,7 +167,7 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
<small><?php _e( 'Show profile photos in the plugin.', 'jetpack' ); ?></small>
</label>
</p>
-
+
<p>
<label for="<?php echo $this->get_field_id( 'stream' ); ?>">
<input type="checkbox" name="<?php echo $this->get_field_name( 'stream' ); ?>" id="<?php echo $this->get_field_id( 'stream' ); ?>" <?php checked( $like_args['stream'] ); ?> />
@@ -177,6 +178,15 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
</p>
<p>
+ <label for="<?php echo $this->get_field_id( 'show_border' ); ?>">
+ <input type="checkbox" name="<?php echo $this->get_field_name( 'show_border' ); ?>" id="<?php echo $this->get_field_id( 'show_border' ); ?>" <?php checked( $like_args['show_border'] ); ?> />
+ <?php _e( 'Show Border', 'jetpack' ); ?>
+ <br />
+ <small><?php _e( 'Show a border around the plugin.', 'jetpack' ); ?></small>
+ </label>
+ </p>
+
+ <p>
<label for="<?php echo $this->get_field_id( 'force_wall' ); ?>">
<input type="checkbox" name="<?php echo $this->get_field_name( 'force_wall' ); ?>" id="<?php echo $this->get_field_id( 'force_wall' ); ?>" <?php checked( $like_args['force_wall'] ); ?> />
<?php _e( 'Show Wall', 'jetpack' ); ?>
@@ -184,10 +194,10 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
<small><?php _e( 'Show the wall for a Places page rather than friend activity.', 'jetpack' ); ?></small>
</label>
</p>
-
+
<?php
}
-
+
function get_default_args() {
$defaults = array(
'href' => '',
@@ -196,13 +206,14 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
'colorscheme' => $this->default_colorscheme,
'show_faces' => true,
'stream' => false,
+ 'show_border' => true,
'header' => false,
'force_wall' => false,
);
return apply_filters( 'jetpack_facebook_likebox_defaults', $defaults );
}
-
+
function normalize_facebook_args( $args ) {
$args = wp_parse_args( (array) $args, $this->get_default_args() );
@@ -219,6 +230,7 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
$args['colorscheme'] = $this->normalize_text_value( $args['colorscheme'], $this->default_colorscheme, $this->allowed_colorschemes );
$args['show_faces'] = (bool) $args['show_faces'];
$args['stream'] = (bool) $args['stream'];
+ $args['show_border'] = (bool) $args['show_border'];
$args['force_wall'] = (bool) $args['force_wall'];
// The height used to be dependent on other widget settings
@@ -233,32 +245,32 @@ class WPCOM_Widget_Facebook_LikeBox extends WP_Widget {
$args['height'] = 432;
}
}
-
+
return $args;
}
-
+
function is_valid_facebook_url( $url ) {
return ( FALSE !== strpos( $url, 'facebook.com' ) ) ? TRUE : FALSE;
}
-
+
function normalize_int_value( $value, $default = 0, $max = 0, $min = 0 ) {
$value = (int) $value;
-
+
if ( $max < $value || $min > $value )
$value = $default;
-
+
return (int) $value;
}
-
+
function normalize_text_value( $value, $default = '', $allowed = array() ) {
$allowed = (array) $allowed;
-
+
if ( empty( $value ) || ( ! empty( $allowed ) && ! in_array( $value, $allowed ) ) )
$value = $default;
-
- return $value;
+
+ return $value;
}
-
+
function guess_locale_from_lang( $lang ) {
if ( 'en' == $lang || 'en_US' == $lang || !$lang ) {
return 'en_US';
diff --git a/plugins/jetpack/modules/widgets/gravatar-profile.css b/plugins/jetpack/modules/widgets/gravatar-profile.css
index 1663ae07..9b1e70cc 100644
--- a/plugins/jetpack/modules/widgets/gravatar-profile.css
+++ b/plugins/jetpack/modules/widgets/gravatar-profile.css
@@ -11,7 +11,7 @@
list-style: none;
display: inline;
}
-
+
.widget-grofile ul.grofile-accounts li::before {
content: "" !important; /* Kubrick :( */
}
diff --git a/plugins/jetpack/modules/widgets/readmill.php b/plugins/jetpack/modules/widgets/readmill.php
index 7729ed3e..2fe189eb 100644
--- a/plugins/jetpack/modules/widgets/readmill.php
+++ b/plugins/jetpack/modules/widgets/readmill.php
@@ -44,7 +44,7 @@ class Jetpack_Readmill_Widget extends WP_Widget {
$size = isset( $instance['size'] ) ? $instance['size'] : $this->default_size;
?>
- <p><?php printf( __( "Just enter the URL to your book, make sure it's a PDF or EPUB file, and you are ready to go. For more help, head to <a href='%s'>the Readmill WordPress Widget support page</a>." ), 'http://en.support.wordpress.com/widgets/readmill/' ); ?></p>
+ <p><?php printf( __( "Just enter the URL to your book, make sure it's a PDF or EPUB file, and you are ready to go. For more help, head to <a href='%s'>the Readmill WordPress Widget support page</a>.", 'jetpack' ), 'http://en.support.wordpress.com/widgets/readmill/' ); ?></p>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'jetpack' ); ?></label>
diff --git a/plugins/jetpack/modules/widgets/rsslinks-widget.php b/plugins/jetpack/modules/widgets/rsslinks-widget.php
index 15309151..cd930ccb 100644
--- a/plugins/jetpack/modules/widgets/rsslinks-widget.php
+++ b/plugins/jetpack/modules/widgets/rsslinks-widget.php
@@ -136,7 +136,7 @@ class Jetpack_RSS_Links_Widget extends WP_Widget {
$type_text = __( 'Comments', 'jetpack' );
$rss_type = 'comments_rss2_url';
}
-
+
$subscribe_to = sprintf( __( 'Subscribe to %s', 'jetpack'), $type_text );
$link_item = '';
diff --git a/plugins/jetpack/modules/widgets/top-posts.php b/plugins/jetpack/modules/widgets/top-posts.php
index b6f2c8d7..ec55fe74 100644
--- a/plugins/jetpack/modules/widgets/top-posts.php
+++ b/plugins/jetpack/modules/widgets/top-posts.php
@@ -57,7 +57,7 @@ class Jetpack_Top_Posts_Widget extends WP_Widget {
}
$count = isset( $instance['count'] ) ? (int) $instance['count'] : 10;
- if ( $count < 1 || 20 < $count ) {
+ if ( $count < 1 || 10 < $count ) {
$count = 10;
}
@@ -75,8 +75,8 @@ class Jetpack_Top_Posts_Widget extends WP_Widget {
</p>
<p>
- <label for="<?php echo $this->get_field_id( 'count' ); ?>"><?php esc_html_e( 'Number of posts to show:', 'jetpack' ); ?></label>
- <input id="<?php echo $this->get_field_id( 'count' ); ?>" name="<?php echo $this->get_field_name( 'count' ); ?>" type="number" value="<?php echo (int) $count; ?>" min="1" max="20" />
+ <label for="<?php echo $this->get_field_id( 'count' ); ?>"><?php esc_html_e( 'Maximum number of posts to show (no more than 10):', 'jetpack' ); ?></label>
+ <input id="<?php echo $this->get_field_id( 'count' ); ?>" name="<?php echo $this->get_field_name( 'count' ); ?>" type="number" value="<?php echo (int) $count; ?>" min="1" max="10" />
</p>
<p>
@@ -101,7 +101,7 @@ class Jetpack_Top_Posts_Widget extends WP_Widget {
}
$instance['count'] = (int) $new_instance['count'];
- if ( $instance['count'] < 1 || 20 < $instance['count'] ) {
+ if ( $instance['count'] < 1 || 10 < $instance['count'] ) {
$instance['count'] = 10;
}
@@ -121,7 +121,7 @@ class Jetpack_Top_Posts_Widget extends WP_Widget {
$title = apply_filters( 'widget_title', $title );
$count = isset( $instance['count'] ) ? (int) $instance['count'] : false;
- if ( $count < 1 || 20 < $count ) {
+ if ( $count < 1 || 10 < $count ) {
$count = 10;
}
@@ -175,7 +175,7 @@ class Jetpack_Top_Posts_Widget extends WP_Widget {
case 'grid' :
wp_enqueue_style( 'widget-grid-and-list' );
foreach ( $posts as &$post ) {
- $image = Jetpack_PostImages::get_image( $post['post_id'] );
+ $image = Jetpack_PostImages::get_image( $post['post_id'], array( 'fallback_to_avatars' => true ) );
$post['image'] = $image['src'];
if ( 'blavatar' != $image['from'] && 'gravatar' != $image['from'] ) {
$size = (int) $get_image_options['avatar_size'];
@@ -268,6 +268,10 @@ class Jetpack_Top_Posts_Widget extends WP_Widget {
if ( !$post )
continue;
+ // Only posts and pages, no attachments
+ if ( 'attachment' == $post->post_type )
+ continue;
+
// hide private and password protected posts
if ( 'publish' != $post->post_status || !empty( $post->post_password ) || empty( $post->ID ) )
continue;
diff --git a/plugins/jetpack/readme.txt b/plugins/jetpack/readme.txt
index f4808dd2..c66fce3c 100644
--- a/plugins/jetpack/readme.txt
+++ b/plugins/jetpack/readme.txt
@@ -1,9 +1,9 @@
=== Jetpack by WordPress.com ===
-Contributors: automattic, apeatling, beaulebens, hugobaeta, Joen, mdawaffe, andy, designsimply, hew, westi, eoigal, tmoorewp, matt, pento, cfinke, daniloercoli, chellycat, gibrown, jblz, jshreve, barry, alternatekev, azaozz, ethitter, johnjamesjacoby, lancewillett, martinremy, nickmomrik, stephdau, yoavf, matveb, jeherve
+Contributors: automattic, alternatekev, andy, apeatling, azaozz, barry, beaulebens, blobaugh, cfinke, chellycat, danielbachhuber, daniloercoli, designsimply, eoigal, ethitter, gibrown, georgestephanis, hew, hugobaeta, iammattthomas, jblz, jeherve, jkudish, Joen, johnjamesjacoby, jshreve, lancewillett, martinremy, matt, matveb, mdawaffe, migueluy, nickmomrik, pento, stephdau, tmoorewp, Viper007Bond, westi, yoavf
Tags: WordPress.com, statistics, stats, views, tweets, twitter, widget, gravatar, hovercards, profile, equations, latex, math, maths, youtube, shortcode, archives, audio, blip, bliptv, dailymotion, digg, flickr, googlevideo, google, googlemaps, kyte, kytetv, livevideo, redlasso, rockyou, rss, scribd, slide, slideshare, soundcloud, vimeo, shortlinks, wp.me, subscriptions, notifications, notes, json, api, rest, mosaic, gallery, slideshow
Requires at least: 3.3
Tested up to: 3.5
-Stable tag: 2.2
+Stable tag: 2.3.3
Supercharge your WordPress site with powerful features previously only available to WordPress.com users.
@@ -36,6 +36,8 @@ Features include:
* Mobile push notifications for new comments via WordPress mobile apps.
* The ability to allow applications to securely authenticate and access your site with your permission.
* Creative formats for your image galleries: mosaic, circles, squares, and a slideshow view.
+* Add post sliders and other highlights to your theme with Featured Content.
+* Search once, get results from everything! A single search box that lets you search posts, pages, comments, and plugins
* and *many* more to come!
Note: The stats portion of Jetpack uses Quantcast to enhance its data.
@@ -58,25 +60,12 @@ Jetpack requires a connection to [WordPress.com](http://wordpress.com/) to enabl
Once you've installed Jetpack, your stats will be available via the "Site Stats" menu which appears in the new Jetpack menu (under your Dashboard menu within WordPress).
-= How do I embed media? =
-
-Use [shortcodes](http://support.wordpress.com/shortcodes/) to embed your media. Currently, Jetpack provides the following shortcodes.
-
-* [[archives]](http://support.wordpress.com/archives-shortcode/)
-* [[audio]](http://support.wordpress.com/audio/)
-* [[blip.tv]](http://support.wordpress.com/videos/bliptv/)
-* [[dailymotion]](http://support.wordpress.com/videos/dailymotion/)
-* [[digg]](http://support.wordpress.com/digg/)
-* [[flickr]](http://support.wordpress.com/videos/flickr-video/)
-* [[googlemaps]](http://en.support.wordpress.com/google-maps/)
-* [[googlevideo]](http://support.wordpress.com/videos/google-video/)
-* [[polldaddy]](http://support.polldaddy.com/wordpress-shortcodes/)
-* [[scribd]](http://support.wordpress.com/scribd/)
-* [[slideshare]](http://support.wordpress.com/slideshows/slideshare/)
-* [[soundcloud]](http://support.wordpress.com/audio/soundcloud-audio-player/)
-* [[videopress]](http://support.wordpress.com/videopress/)
-* [[vimeo]](http://support.wordpress.com/videos/vimeo/)
-* [[youtube]](http://support.wordpress.com/videos/youtube/)
+= How do I contribute to Jetpack? =
+
+Easy! There are a couple of ways (more coming soon):
+
+* Give us a hand answering questions in our [support forum](http://wordpress.org/support/plugin/jetpack)
+* Report bugs, with reproduction steps, or post patches on our [Trac](http://plugins.trac.wordpress.org/newticket?component=jetpack)
== Screenshots ==
@@ -91,6 +80,185 @@ Use [shortcodes](http://support.wordpress.com/shortcodes/) to embed your media.
== Changelog ==
+= 2.3.3 =
+* 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 =
+* 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 =
+* 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 =
+* 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 =
+* 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 =
+* Bug Fix: JSON API compat file include was not assigning a variable correctly, thus throwing errors. This has been resolved.
+
+= 2.2.3 =
+* 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 (<a href="http://wordpress.org/support/topic/two-issues-with-jetpack-css-module?replies=9">ref</a>)
+* 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 <code>minileven_actual_current_theme()</code> 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 =
+* 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 =
+* 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 =
* 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).