From ee53e4985c1f8ac6a3bb84837ce52bce796c6e8b Mon Sep 17 00:00:00 2001 From: "Jake F - @samouri" Date: Thu, 23 Mar 2017 15:48:21 -0400 Subject: [PATCH 1/2] add in precommit hook & disable all style rules from eslintrc --- .eslintrc.js | 8 ++++++-- bin/pre-commit | 6 ++++++ bin/prettify-file.sh | 15 +++++++++++++++ package.json | 2 ++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 bin/prettify-file.sh diff --git a/.eslintrc.js b/.eslintrc.js index d8b44e9c6cf61..9ad3a78dd2515 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,10 @@ module.exports = { root: true, - 'extends': 'wpcalypso/react', + 'extends': [ + 'wpcalypso/react', + 'prettier', + 'prettier/react' + ], parser: 'babel-eslint', env: { browser: true, @@ -17,4 +21,4 @@ module.exports = { 'no-restricted-modules': [ 2, 'lib/sites-list', 'lib/mixins/data-observe' ], 'no-unused-expressions': 0, // Allows Chai `expect` expressions } -}; \ No newline at end of file +}; diff --git a/bin/pre-commit b/bin/pre-commit index f8a4abf95a2f5..100e92cff067e 100755 --- a/bin/pre-commit +++ b/bin/pre-commit @@ -12,6 +12,12 @@ fi pass=true +printf "\nFormatting .jsx and .js:\n" + +for file in ${files}; do + ./bin/prettify-file.sh ${file} +done + printf "\nValidating .jsx and .js:\n" ./bin/run-lint $(git diff --cached --name-only client/ server/ test/ | grep ".jsx*$") -- --diff=index diff --git a/bin/prettify-file.sh b/bin/prettify-file.sh new file mode 100644 index 0000000000000..571451543b48c --- /dev/null +++ b/bin/prettify-file.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +file="$1" +printf $file +if [[ ! $file =~ ^client/[^\.]+\.jsx?$ ]]; then + printf "\nNot a prettifiable file\n" + exit 0 +fi + +if [ ! -f ./node_modules/.bin/prettier ]; then + printf "\n'Prettier' not found, please run 'npm install' first\n" + exit 1 +fi + +./node_modules/.bin/prettier --print-width=100 --single-quote --tab-width=4 --trailing-comma=es5 --write ${file} diff --git a/package.json b/package.json index 86b41a24f7376..6bd1acebb741d 100644 --- a/package.json +++ b/package.json @@ -168,6 +168,7 @@ "esformatter-special-bangs": "1.0.1", "eslines": "0.0.11", "eslint": "3.8.1", + "eslint-config-prettier": "1.5.0", "eslint-config-wpcalypso": "0.6.0", "eslint-plugin-react": "6.4.1", "eslint-plugin-wpcalypso": "3.0.2", @@ -180,6 +181,7 @@ "mockery": "1.7.0", "nock": "8.0.0", "nodemon": "1.4.1", + "prettier": "0.22.0", "react-addons-test-utils": "15.4.0", "react-hot-loader": "1.3.0", "react-test-env": "0.2.0", From c0d8f93b3421eda48e95fe87627f59692dc31f1d Mon Sep 17 00:00:00 2001 From: "Jake F - @samouri" Date: Thu, 23 Mar 2017 17:03:54 -0400 Subject: [PATCH 2/2] Use Prettier and format all the things --- bin/prettify-file.sh | 0 client/account-recovery/controller.js | 96 +- .../forgot-username-form/index.jsx | 240 +- .../forgot-username-form/test/index.jsx | 241 +- .../forgot-username/index.jsx | 14 +- client/account-recovery/index.js | 50 +- .../account-recovery/lost-password/index.jsx | 14 +- .../lost-password-form/index.jsx | 202 +- .../lost-password-form/test/index.jsx | 60 +- .../account-recovery/reset-password/index.jsx | 14 +- .../reset-password-confirm-form/index.jsx | 80 +- .../reset-password-email-form/index.jsx | 54 +- .../reset-password-form/index.jsx | 198 +- .../reset-password-form/reset-option-set.jsx | 76 +- .../reset-password-form/test/index.jsx | 168 +- .../reset-password-sms-form/index.jsx | 53 +- .../transaction-id-form/index.jsx | 157 +- .../transaction-id-form/test/index.jsx | 76 +- client/auth/auth-code-button.jsx | 90 +- client/auth/connect.jsx | 81 +- client/auth/controller.js | 154 +- client/auth/index.js | 10 +- client/auth/login.jsx | 376 +- client/auth/test/login.jsx | 110 +- client/blocks/app-promo/index.jsx | 225 +- client/blocks/app-promo/test/index.jsx | 120 +- .../author-compact-profile/docs/example.jsx | 44 +- .../blocks/author-compact-profile/index.jsx | 142 +- .../author-compact-profile/placeholder.jsx | 30 +- .../blocks/author-selector/docs/example.jsx | 40 +- client/blocks/author-selector/index.jsx | 542 +- client/blocks/comment-button/docs/example.jsx | 30 +- client/blocks/comment-button/index.jsx | 103 +- client/blocks/comments/comment-count.jsx | 44 +- client/blocks/comments/comment-likes.jsx | 111 +- client/blocks/comments/form.jsx | 471 +- client/blocks/comments/helper.jsx | 38 +- .../blocks/comments/post-comment-content.jsx | 34 +- client/blocks/comments/post-comment-list.jsx | 470 +- .../comments/post-comment-with-error.jsx | 74 +- client/blocks/comments/post-comment.jsx | 485 +- client/blocks/comments/post-trackback.jsx | 67 +- .../blocks/credit-card-form/docs/example.jsx | 27 +- client/blocks/credit-card-form/index.jsx | 578 +- .../credit-card-form/loading-placeholder.jsx | 25 +- .../blocks/daily-post-button/docs/example.jsx | 12 +- client/blocks/daily-post-button/helper.js | 14 +- client/blocks/daily-post-button/index.jsx | 284 +- .../blocks/daily-post-button/test/fixtures.js | 43 +- .../blocks/daily-post-button/test/helper.js | 42 +- .../blocks/daily-post-button/test/index.jsx | 188 +- .../blocks/design-menu/design-menu-header.jsx | 47 +- .../design-menu/design-menu-panel/index.jsx | 34 +- .../blocks/design-menu/design-tool-data.jsx | 149 +- .../blocks/design-menu/design-tool-list.jsx | 76 +- client/blocks/design-menu/index.jsx | 291 +- .../docs/example.jsx | 162 +- .../disconnect-jetpack-dialog/index.jsx | 281 +- .../blocks/dismissible-card/docs/example.jsx | 41 +- client/blocks/dismissible-card/index.jsx | 94 +- client/blocks/domain-to-plan-nudge/index.jsx | 191 +- client/blocks/edit-gravatar/constants.js | 8 +- client/blocks/edit-gravatar/index.jsx | 323 +- client/blocks/edit-gravatar/test/index.jsx | 310 +- .../blocks/eligibility-warnings/hold-list.jsx | 233 +- client/blocks/eligibility-warnings/index.jsx | 253 +- .../eligibility-warnings/warning-list.jsx | 75 +- client/blocks/follow-button/button.jsx | 152 +- client/blocks/follow-button/docs/example.jsx | 46 +- client/blocks/follow-button/index.jsx | 111 +- client/blocks/follow-button/test/button.js | 12 +- client/blocks/followers-count/index.jsx | 52 +- client/blocks/image-editor/docs/example.jsx | 189 +- .../image-editor/image-editor-buttons.jsx | 123 +- .../image-editor/image-editor-canvas.jsx | 572 +- .../blocks/image-editor/image-editor-crop.jsx | 1002 +- .../image-editor/image-editor-toolbar.jsx | 389 +- client/blocks/image-editor/index.jsx | 495 +- client/blocks/image-editor/utils.js | 19 +- client/blocks/like-button/button.jsx | 190 +- client/blocks/like-button/docs/example.jsx | 99 +- client/blocks/like-button/icons.jsx | 14 +- client/blocks/like-button/index.jsx | 99 +- client/blocks/nps-survey/docs/example.jsx | 84 +- client/blocks/nps-survey/index.jsx | 185 +- .../nps-survey/recommendation-option.jsx | 54 +- .../nps-survey/recommendation-select.jsx | 46 +- client/blocks/plan-storage/bar.jsx | 111 +- client/blocks/plan-storage/docs/example.jsx | 128 +- client/blocks/plan-storage/index.jsx | 92 +- .../plan-thank-you-card/docs/example.jsx | 16 +- client/blocks/plan-thank-you-card/index.jsx | 107 +- client/blocks/post-actions/index.jsx | 159 +- .../blocks/post-edit-button/docs/example.jsx | 32 +- client/blocks/post-edit-button/index.jsx | 28 +- client/blocks/post-item/docs/example.jsx | 51 +- client/blocks/post-item/index.jsx | 84 +- client/blocks/post-likes/docs/example.jsx | 10 +- client/blocks/post-likes/index.jsx | 90 +- .../post-relative-time/docs/example.jsx | 48 +- client/blocks/post-relative-time/index.jsx | 53 +- .../blocks/post-relative-time/test/index.jsx | 159 +- client/blocks/post-status/docs/example.jsx | 79 +- client/blocks/post-status/index.jsx | 111 +- client/blocks/post-status/test/index.jsx | 157 +- .../product-purchase-features/index.jsx | 14 +- .../advertising-removed.jsx | 35 +- .../business-onboarding.jsx | 36 +- .../custom-domain.jsx | 15 +- .../customize-theme.jsx | 48 +- .../find-new-theme.jsx | 28 +- .../google-analytics-stats.jsx | 28 +- .../google-vouchers.jsx | 14 +- .../product-purchase-features-list/index.jsx | 462 +- .../jetpack-anti-spam.jsx | 26 +- .../jetpack-backup-security.jsx | 33 +- .../jetpack-return-to-dashboard.jsx | 26 +- .../jetpack-surveys-polls.jsx | 32 +- .../jetpack-wordpress-com.jsx | 42 +- .../monetize-site.jsx | 34 +- .../video-audio-posts.jsx | 34 +- .../blocks/reader-author-and-site/index.jsx | 76 +- .../reader-author-link/docs/example.jsx | 13 +- client/blocks/reader-author-link/index.jsx | 74 +- .../blocks/reader-author-link/test/index.jsx | 104 +- client/blocks/reader-avatar/docs/example.jsx | 26 +- client/blocks/reader-avatar/index.jsx | 121 +- .../reader-combined-card/docs/example.jsx | 10 +- client/blocks/reader-combined-card/index.jsx | 201 +- .../placeholders/post.jsx | 26 +- client/blocks/reader-combined-card/post.jsx | 253 +- client/blocks/reader-excerpt/index.jsx | 31 +- .../reader-export-button/docs/example.jsx | 10 +- client/blocks/reader-export-button/index.jsx | 94 +- client/blocks/reader-featured-image/index.jsx | 45 +- .../reader-featured-video/docs/example.jsx | 49 +- client/blocks/reader-featured-video/index.jsx | 220 +- client/blocks/reader-feed-header/index.jsx | 187 +- client/blocks/reader-full-post/back.jsx | 22 +- .../reader-full-post/docs/header-example.jsx | 86 +- .../reader-full-post/featured-image.jsx | 46 +- .../blocks/reader-full-post/header-tags.jsx | 37 +- client/blocks/reader-full-post/header.jsx | 107 +- client/blocks/reader-full-post/index.jsx | 923 +- .../reader-full-post/placeholders/content.jsx | 12 +- .../reader-full-post/placeholders/header.jsx | 20 +- .../reader-full-post/test/featured-image.jsx | 17 +- .../blocks/reader-full-post/unavailable.jsx | 44 +- client/blocks/reader-post-actions/index.jsx | 198 +- client/blocks/reader-post-card/blocked.jsx | 67 +- client/blocks/reader-post-card/byline.jsx | 225 +- .../blocks/reader-post-card/docs/example.jsx | 18 +- .../blocks/reader-post-card/docs/fixtures.js | 308 +- client/blocks/reader-post-card/gallery.jsx | 89 +- client/blocks/reader-post-card/index.jsx | 399 +- client/blocks/reader-post-card/photo.jsx | 234 +- client/blocks/reader-post-card/standard.jsx | 52 +- .../reader-post-options-menu/docs/example.jsx | 45 +- .../blocks/reader-post-options-menu/index.jsx | 264 +- .../reader-related-card-v2/docs/example.jsx | 236 +- .../blocks/reader-related-card-v2/index.jsx | 237 +- .../reader-related-card/docs/example.jsx | 164 +- client/blocks/reader-related-card/index.jsx | 62 +- .../reader-site-stream-link/docs/example.jsx | 27 +- .../blocks/reader-site-stream-link/index.jsx | 61 +- .../docs/example.jsx | 101 +- .../reader-subscription-list-item/index.jsx | 118 +- client/blocks/reader-visit-link/index.jsx | 55 +- client/blocks/site-icon/docs/example.jsx | 8 +- client/blocks/site-icon/index.jsx | 101 +- client/blocks/site-preview/index.jsx | 38 +- client/blocks/site/index.jsx | 229 +- client/blocks/site/placeholder.jsx | 41 +- client/blocks/stats-sparkline/index.jsx | 75 +- client/blocks/taxonomy-manager/index.jsx | 162 +- client/blocks/taxonomy-manager/list-item.jsx | 390 +- client/blocks/taxonomy-manager/list.jsx | 335 +- client/blocks/term-form-dialog/index.jsx | 649 +- client/blocks/term-tree-selector/index.jsx | 137 +- .../blocks/term-tree-selector/no-results.jsx | 59 +- client/blocks/term-tree-selector/search.jsx | 38 +- client/blocks/term-tree-selector/terms.jsx | 852 +- .../blocks/upgrade-nudge-expanded/index.jsx | 221 +- client/blocks/url-preview/index.jsx | 172 +- client/boot/index.js | 795 +- client/components/accordion/docs/example.jsx | 142 +- client/components/accordion/index.jsx | 104 +- client/components/accordion/section.jsx | 18 +- client/components/accordion/status.jsx | 105 +- client/components/accordion/test/index.jsx | 194 +- client/components/accordion/test/status.jsx | 83 +- client/components/animate/index.jsx | 12 +- client/components/async-load/index.jsx | 106 +- client/components/auto-direction/direction.js | 1590 +- client/components/auto-direction/index.jsx | 226 +- client/components/banner/docs/example.jsx | 86 +- client/components/banner/index.jsx | 421 +- .../components/bulk-select/docs/example.jsx | 100 +- client/components/bulk-select/index.jsx | 97 +- client/components/bulk-select/test/index.js | 130 +- .../components/button-group/docs/example.jsx | 119 +- client/components/button-group/index.jsx | 39 +- client/components/button-group/test/index.js | 70 +- client/components/button/docs/example.jsx | 372 +- client/components/button/index.jsx | 86 +- client/components/button/test/index.js | 178 +- client/components/card/compact.jsx | 24 +- client/components/card/docs/example.jsx | 111 +- client/components/card/index.jsx | 77 +- client/components/card/test/index.js | 92 +- client/components/chart/bar-container.jsx | 91 +- client/components/chart/bar.jsx | 303 +- client/components/chart/index.jsx | 291 +- client/components/chart/label.jsx | 36 +- client/components/chart/legend.jsx | 148 +- client/components/chart/x-axis.jsx | 160 +- .../clipboard-button-input/docs/example.jsx | 22 +- .../clipboard-button-input/index.jsx | 115 +- client/components/count/docs/example.jsx | 4 +- client/components/count/index.jsx | 18 +- client/components/count/test/index.jsx | 22 +- .../credit-card-form-fields/index.jsx | 191 +- .../loading-placeholder.jsx | 58 +- client/components/data/cart/index.jsx | 32 +- client/components/data/checkout/index.jsx | 36 +- .../components/data/document-head/index.jsx | 138 +- .../data/domain-management/dns/index.jsx | 87 +- .../email-forwarding/index.jsx | 82 +- .../data/domain-management/email/index.jsx | 195 +- .../data/domain-management/index.jsx | 119 +- .../domain-management/nameservers/index.jsx | 120 +- .../domain-management/site-redirect/index.jsx | 63 +- .../data/domain-management/transfer/index.jsx | 97 +- .../data/domain-management/whois/index.jsx | 126 +- .../data/email-followers-data/index.jsx | 192 +- .../components/data/followers-data/index.jsx | 188 +- .../media-library-selected-data/index.jsx | 66 +- .../components/data/media-list-data/index.jsx | 155 +- .../data/media-list-data/test/utils.js | 52 +- .../components/data/media-list-data/utils.js | 52 +- .../data/media-validation-data/index.jsx | 66 +- .../query-account-recovery-settings/index.jsx | 26 +- .../data/query-active-theme/index.jsx | 56 +- .../data/query-atat-eligibility/index.jsx | 52 +- .../query-atat-eligibility/test/index.jsx | 121 +- .../data/query-billing-transactions/index.jsx | 36 +- .../data/query-canonical-theme/index.jsx | 32 +- .../data/query-country-states/index.jsx | 48 +- .../data/query-domains-suggestions/index.jsx | 106 +- client/components/data/query-geo/index.jsx | 25 +- .../data/query-happiness-engineers/index.jsx | 36 +- .../data/query-jetpack-connection/index.jsx | 71 +- .../data/query-jetpack-jumpstart/index.jsx | 68 +- .../data/query-jetpack-modules/index.jsx | 68 +- .../data/query-jetpack-plugins/index.jsx | 58 +- .../data/query-jetpack-settings/index.jsx | 68 +- .../data/query-keyring-connections/index.jsx | 34 +- .../data/query-keyring-services/index.jsx | 31 +- .../data/query-media-storage/index.jsx | 90 +- client/components/data/query-media/index.jsx | 84 +- client/components/data/query-olark/index.jsx | 37 +- .../data/query-page-templates/index.jsx | 72 +- client/components/data/query-plans/index.jsx | 36 +- .../data/query-plugin-keys/index.jsx | 68 +- .../data/query-post-counts/index.jsx | 71 +- .../data/query-post-formats/index.jsx | 68 +- .../data/query-post-likes/index.jsx | 75 +- .../data/query-post-stats/index.jsx | 123 +- .../data/query-post-types/index.jsx | 78 +- client/components/data/query-posts/index.jsx | 97 +- .../data/query-preferences/index.jsx | 32 +- .../data/query-products-list/index.jsx | 27 +- .../query-publicize-connections/index.jsx | 76 +- .../data/query-reader-feed/index.jsx | 69 +- .../data/query-reader-followed-tags/index.jsx | 23 +- .../data/query-reader-list/index.jsx | 76 +- .../data/query-reader-lists/index.jsx | 49 +- .../data/query-reader-related-posts/index.jsx | 87 +- .../data/query-reader-site/index.jsx | 69 +- .../data/query-reader-tag-images/index.jsx | 61 +- .../data/query-reader-tag/index.jsx | 25 +- .../data/query-reader-teams/index.jsx | 36 +- .../data/query-reader-thumbnails/index.jsx | 59 +- .../data/query-sharing-buttons/index.js | 66 +- .../components/data/query-shortcode/index.jsx | 68 +- .../data/query-site-domains/index.jsx | 82 +- .../data/query-site-guided-transfer/index.jsx | 65 +- .../data/query-site-plans/index.jsx | 82 +- .../data/query-site-purchases/index.jsx | 52 +- .../data/query-site-roles/index.jsx | 68 +- .../data/query-site-settings/index.js | 66 +- .../data/query-site-stats/index.jsx | 118 +- .../data/query-site-updates/index.js | 94 +- .../data/query-site-vouchers/index.jsx | 79 +- client/components/data/query-sites/index.jsx | 80 +- .../data/query-stored-cards/index.jsx | 34 +- .../data/query-taxonomies/index.jsx | 81 +- client/components/data/query-terms/index.jsx | 83 +- client/components/data/query-theme/index.jsx | 65 +- client/components/data/query-themes/index.jsx | 95 +- .../index.jsx | 34 +- .../components/data/query-timezones/index.jsx | 36 +- .../data/query-user-purchases/index.jsx | 72 +- .../data/query-users-suggestions/index.jsx | 82 +- .../data/query-wordads-status/index.jsx | 56 +- .../data/store-connection/index.jsx | 114 +- client/components/data/viewers-data/index.jsx | 150 +- client/components/date-picker/day.jsx | 218 +- .../components/date-picker/docs/example.jsx | 100 +- client/components/date-picker/index.jsx | 249 +- client/components/dialog/dialog-base.jsx | 194 +- client/components/dialog/index.jsx | 69 +- .../domain-mapping-suggestion/index.jsx | 109 +- .../domains/domain-product-price/index.jsx | 173 +- .../domain-registration-suggestion/index.jsx | 123 +- .../domains/domain-search-results/index.jsx | 327 +- .../domains/domain-suggestion-flag/index.jsx | 32 +- .../domains/domain-suggestion/index.jsx | 112 +- .../domains/domain-suggestion/test/index.js | 49 +- .../example-domain-suggestions/index.jsx | 98 +- .../domains/map-domain-step/index.jsx | 357 +- .../domains/register-domain-step/index.jsx | 997 +- client/components/draggable/index.jsx | 340 +- client/components/drop-zone/docs/example.jsx | 94 +- client/components/drop-zone/index.jsx | 451 +- client/components/drop-zone/test/index.jsx | 512 +- .../components/ellipsis-menu/docs/example.jsx | 16 +- client/components/ellipsis-menu/index.jsx | 140 +- .../email-unverified-notice.jsx | 353 +- .../email-verification-gate.jsx | 99 +- client/components/email-verification/index.js | 37 +- client/components/embed-container/index.jsx | 303 +- client/components/emojify/docs/example.jsx | 14 +- client/components/emojify/index.jsx | 50 +- client/components/empty-component/index.jsx | 2 +- .../empty-content/empty-content.jsx | 271 +- .../feature-unavailable/index.jsx | 43 +- .../empty-content/no-sites-message/index.jsx | 25 +- .../components/external-link/docs/example.jsx | 27 +- client/components/external-link/index.jsx | 105 +- client/components/faq/docs/example.jsx | 95 +- client/components/faq/faq-item.jsx | 21 +- client/components/faq/index.jsx | 21 +- .../feature-example/docs/example.jsx | 96 +- client/components/feature-example/index.jsx | 24 +- .../components/feature-example/test/index.js | 20 +- .../components/file-picker/docs/example.jsx | 94 +- client/components/file-picker/index.jsx | 44 +- client/components/first-view/index.jsx | 227 +- .../components/foldable-card/docs/example.jsx | 142 +- client/components/foldable-card/index.jsx | 293 +- .../forms/clipboard-button/docs/example.jsx | 58 +- .../forms/clipboard-button/index.jsx | 108 +- .../forms/counted-textarea/docs/example.jsx | 50 +- .../forms/counted-textarea/index.jsx | 134 +- .../forms/counted-textarea/test/index.jsx | 291 +- client/components/forms/docs/example.jsx | 555 +- client/components/forms/form-button/index.jsx | 54 +- .../forms/form-buttons-bar/index.jsx | 30 +- .../components/forms/form-checkbox/index.jsx | 27 +- .../forms/form-country-select/index.jsx | 69 +- .../components/forms/form-fieldset/index.jsx | 28 +- .../forms/form-input-validation/index.jsx | 55 +- client/components/forms/form-label/index.jsx | 28 +- client/components/forms/form-legend/index.jsx | 28 +- .../forms/form-password-input/index.jsx | 117 +- .../forms/form-phone-input/index.jsx | 288 +- .../forms/form-phone-input/test/index.jsx | 178 +- .../test/mocks/mock-countries-list-empty.js | 10 +- .../test/mocks/mock-countries-list.js | 30 +- .../forms/form-phone-media-input/index.jsx | 54 +- client/components/forms/form-radio/index.jsx | 30 +- client/components/forms/form-range/index.jsx | 97 +- .../forms/form-section-heading/index.jsx | 28 +- client/components/forms/form-select/index.jsx | 36 +- .../forms/form-setting-explanation/index.jsx | 52 +- .../components/forms/form-tel-input/index.jsx | 16 +- .../form-text-input-with-action/index.jsx | 190 +- .../form-text-input-with-affixes/index.jsx | 52 +- .../forms/form-text-input/index.jsx | 67 +- .../forms/form-text-input/test/index.jsx | 114 +- .../components/forms/form-textarea/index.jsx | 28 +- .../components/forms/form-toggle/compact.jsx | 33 +- client/components/forms/form-toggle/index.jsx | 173 +- .../forms/form-toggle/test/index.jsx | 219 +- client/components/forms/language-selector.jsx | 44 +- .../components/forms/multi-checkbox/index.jsx | 101 +- .../forms/multi-checkbox/test/index.jsx | 150 +- .../components/forms/range/docs/example.jsx | 58 +- client/components/forms/range/index.jsx | 171 +- client/components/forms/range/test/index.jsx | 102 +- client/components/forms/select-opt-groups.jsx | 32 +- .../components/forms/sortable-list/index.jsx | 673 +- client/components/forms/us-state-selector.jsx | 146 +- client/components/gallery-shortcode/index.jsx | 207 +- client/components/gauge/docs/example.jsx | 21 +- client/components/gauge/index.jsx | 153 +- .../global-notices/docs/example.jsx | 82 +- client/components/global-notices/index.jsx | 163 +- client/components/gravatar/docs/example.jsx | 24 +- client/components/gravatar/index.jsx | 146 +- client/components/gravatar/test/index.jsx | 245 +- .../happiness-support/docs/example.jsx | 20 +- client/components/happiness-support/index.jsx | 183 +- client/components/happychat/agent-w/index.jsx | 346 +- client/components/happychat/autoscroll.js | 96 +- client/components/happychat/button.jsx | 45 +- client/components/happychat/composer.jsx | 103 +- client/components/happychat/functional.js | 47 +- client/components/happychat/helpers.js | 26 +- client/components/happychat/index.jsx | 195 +- client/components/happychat/notices.jsx | 82 +- client/components/happychat/scrollbleed.js | 102 +- client/components/happychat/timeline.jsx | 293 +- client/components/header-cake/back.jsx | 101 +- .../components/header-cake/docs/example.jsx | 41 +- client/components/header-cake/index.jsx | 81 +- client/components/hr-with-text/index.jsx | 14 +- .../image-preloader/docs/example.jsx | 11 +- client/components/image-preloader/index.jsx | 217 +- client/components/infinite-list/index.jsx | 775 +- .../components/infinite-list/scroll-helper.js | 922 +- .../infinite-list/test/scroll-helper.js | 1216 +- .../components/info-popover/docs/example.jsx | 98 +- client/components/info-popover/index.jsx | 143 +- .../components/input-chrono/docs/example.jsx | 79 +- client/components/input-chrono/index.jsx | 179 +- client/components/logged-out-form/footer.jsx | 28 +- client/components/logged-out-form/index.jsx | 32 +- .../components/logged-out-form/link-item.jsx | 32 +- client/components/logged-out-form/links.jsx | 34 +- client/components/main/index.jsx | 28 +- .../cancel-purchase-form/index.jsx | 911 +- .../mobile-back-to-sidebar/index.jsx | 43 +- client/components/notice/docs/example.jsx | 212 +- client/components/notice/index.jsx | 163 +- client/components/notice/notice-action.jsx | 62 +- client/components/notice/test/index.js | 72 +- client/components/olark-chat-button/index.jsx | 92 +- client/components/olark-chatbox/index.jsx | 160 +- .../components/payment-logo/docs/example.jsx | 30 +- client/components/payment-logo/index.jsx | 26 +- .../components/phone-input/country-flag.jsx | 112 +- client/components/phone-input/data.js | 13158 ++++++++-------- client/components/phone-input/index.jsx | 346 +- client/components/phone-input/phone-number.js | 303 +- .../phone-input/test/test-phone-number.js | 492 +- client/components/plans/plan-icon/index.jsx | 264 +- client/components/plans/plan-price/index.jsx | 158 +- .../plans/premium-popover/index.jsx | 224 +- client/components/popover/docs/example.jsx | 238 +- client/components/popover/index.jsx | 736 +- client/components/popover/menu-item.jsx | 89 +- client/components/popover/menu.jsx | 294 +- client/components/popover/util.js | 556 +- client/components/post-excerpt/index.jsx | 61 +- client/components/post-list-fetcher/index.jsx | 287 +- client/components/post-schedule/clock.jsx | 454 +- .../components/post-schedule/docs/example.jsx | 477 +- .../post-schedule/header-controls.jsx | 64 +- client/components/post-schedule/header.jsx | 113 +- client/components/post-schedule/index.jsx | 360 +- client/components/post-schedule/test/index.js | 219 +- client/components/post-schedule/utils.js | 106 +- .../components/progress-bar/docs/example.jsx | 63 +- client/components/progress-bar/index.jsx | 107 +- client/components/progress-bar/test/index.jsx | 72 +- .../components/progress-indicator/index.jsx | 76 +- client/components/pulsing-dot/index.jsx | 92 +- client/components/purchase-detail/index.jsx | 151 +- .../purchase-detail/purchase-button.jsx | 64 +- .../components/purchase-detail/tip-info.jsx | 24 +- client/components/rating/docs/example.jsx | 21 +- client/components/rating/index.jsx | 119 +- client/components/rating/test/index.js | 115 +- client/components/reader-main/index.jsx | 18 +- client/components/related-posts-v2/index.jsx | 99 +- client/components/related-posts/index.jsx | 98 +- client/components/resizable-iframe/index.jsx | 236 +- client/components/ribbon/docs/example.jsx | 69 +- client/components/ribbon/index.jsx | 16 +- client/components/root-child/index.jsx | 94 +- client/components/root-child/test/index.jsx | 155 +- client/components/search-card/index.jsx | 62 +- client/components/search/docs/example.jsx | 38 +- client/components/search/index.jsx | 765 +- client/components/search/test/index.jsx | 102 +- .../section-header/docs/example.jsx | 67 +- client/components/section-header/index.jsx | 50 +- .../components/section-nav/docs/example.jsx | 354 +- client/components/section-nav/index.jsx | 323 +- client/components/section-nav/item.jsx | 115 +- client/components/section-nav/segmented.jsx | 97 +- client/components/section-nav/tabs.jsx | 316 +- client/components/section-nav/test/index.jsx | 220 +- .../segmented-control/docs/example.jsx | 269 +- client/components/segmented-control/index.jsx | 421 +- client/components/segmented-control/item.jsx | 85 +- .../select-dropdown/docs/example.jsx | 262 +- client/components/select-dropdown/index.jsx | 750 +- client/components/select-dropdown/item.jsx | 88 +- client/components/select-dropdown/label.jsx | 15 +- .../components/select-dropdown/separator.jsx | 3 +- .../components/select-dropdown/test/index.js | 597 +- .../components/select-dropdown/test/item.js | 102 +- client/components/select/docs/example.jsx | 76 +- client/components/seo-preview-pane/index.jsx | 439 +- .../components/seo/facebook-preview/index.jsx | 95 +- client/components/seo/helpers.js | 20 +- .../seo/meta-title-editor/index.jsx | 146 +- .../seo/meta-title-editor/mappings.js | 86 +- .../seo/meta-title-editor/test/index.js | 206 +- .../seo/preview-upgrade-nudge/index.jsx | 271 +- client/components/seo/reader-preview/index.js | 131 +- .../components/seo/search-preview/index.jsx | 83 +- .../components/seo/twitter-preview/index.jsx | 78 +- client/components/shortcode/data.jsx | 44 +- client/components/shortcode/frame.jsx | 130 +- client/components/shortcode/index.jsx | 109 +- .../components/sidebar-navigation/index.jsx | 66 +- client/components/signup-form/index.jsx | 922 +- client/components/signup-form/social.jsx | 76 +- client/components/signup-site-title/index.js | 126 +- .../components/site-selector-modal/index.jsx | 178 +- client/components/site-selector/add-site.jsx | 205 +- client/components/site-selector/index.jsx | 850 +- client/components/site-title-example/index.js | 53 +- client/components/site-title/index.jsx | 85 +- .../components/site-users-fetcher/index.jsx | 214 +- .../sites-dropdown/docs/example.jsx | 13 +- client/components/sites-dropdown/index.jsx | 140 +- .../components/sites-dropdown/test/index.js | 226 +- .../test/lib/sites-list/index.js | 53 +- client/components/sites-popover/index.jsx | 167 +- client/components/social-buttons/facebook.js | 186 +- client/components/social-buttons/google.js | 161 +- .../spinner-button/docs/example.jsx | 30 +- client/components/spinner-button/index.jsx | 91 +- .../components/spinner-line/docs/example.jsx | 8 +- client/components/spinner-line/index.jsx | 12 +- client/components/spinner/docs/example.jsx | 43 +- client/components/spinner/index.jsx | 216 +- .../stat-update-indicator/index.jsx | 99 +- client/components/sticky-panel/index.jsx | 211 +- client/components/suggestions/index.jsx | 490 +- client/components/textarea-autosize/index.jsx | 47 +- client/components/thank-you-card/index.jsx | 141 +- client/components/theme/docs/example.jsx | 67 +- client/components/theme/index.jsx | 348 +- client/components/theme/more-button.jsx | 227 +- client/components/theme/test/index.jsx | 267 +- .../components/themes-list/docs/example.jsx | 106 +- client/components/themes-list/index.jsx | 190 +- client/components/themes-list/test/index.jsx | 133 +- client/components/timezone/docs/example.jsx | 42 +- client/components/timezone/index.jsx | 150 +- client/components/tinymce/i18n.js | 135 +- client/components/tinymce/index.jsx | 911 +- .../tinymce/plugins/advanced/plugin.jsx | 184 +- .../plugins/after-the-deadline/core.js | 1085 +- .../plugins/after-the-deadline/plugin.js | 936 +- .../tinymce/plugins/calypso-alert/alert.jsx | 70 +- .../tinymce/plugins/calypso-alert/plugin.jsx | 94 +- .../contact-form/dialog/field-edit-button.jsx | 88 +- .../contact-form/dialog/field-header.jsx | 120 +- .../contact-form/dialog/field-list.jsx | 68 +- .../dialog/field-remove-button.jsx | 70 +- .../plugins/contact-form/dialog/field.jsx | 223 +- .../plugins/contact-form/dialog/index.jsx | 170 +- .../plugins/contact-form/dialog/locales.js | 56 +- .../contact-form/dialog/navigation.jsx | 55 +- .../plugins/contact-form/dialog/settings.jsx | 116 +- .../contact-form/dialog/validations.js | 26 +- .../tinymce/plugins/contact-form/plugin.jsx | 162 +- .../plugins/contact-form/shortcode-utils.js | 94 +- .../plugins/contact-form/test/shortcode.js | 298 +- .../plugins/contact-form/test/validations.js | 218 +- .../plugins/editor-button-analytics/plugin.js | 127 +- .../tinymce/plugins/embed-reversal/plugin.js | 115 +- .../plugins/insert-menu/menu-items.jsx | 30 +- .../tinymce/plugins/insert-menu/plugin.jsx | 48 +- .../tinymce/plugins/media/advanced/index.jsx | 115 +- .../tinymce/plugins/media/drop-zone.jsx | 246 +- .../tinymce/plugins/media/plugin.jsx | 1561 +- .../plugins/media/restrict-size/index.js | 96 +- .../plugins/media/restrict-size/test/index.js | 178 +- .../plugins/mentions/editor-mention.jsx | 6 +- .../tinymce/plugins/mentions/mentions.jsx | 505 +- .../tinymce/plugins/mentions/plugin.jsx | 72 +- .../plugins/mentions/suggestion-list.jsx | 74 +- .../tinymce/plugins/mentions/suggestion.jsx | 92 +- .../tinymce/plugins/toolbar-pin/plugin.js | 102 +- .../plugins/touch-scroll-toolbar/plugin.js | 145 +- .../plugins/wpcom-autoresize/plugin.js | 387 +- .../tinymce/plugins/wpcom-charmap/charmap.jsx | 626 +- .../tinymce/plugins/wpcom-charmap/plugin.js | 70 +- .../tinymce/plugins/wpcom-help/help-modal.jsx | 236 +- .../tinymce/plugins/wpcom-help/plugin.js | 78 +- .../plugins/wpcom-sourcecode/plugin.js | 102 +- .../plugins/wpcom-sourcecode/test/plugin.js | 162 +- .../tinymce/plugins/wpcom-tabindex/plugin.js | 48 +- .../plugins/wpcom-track-paste/plugin.js | 74 +- .../plugins/wpcom-view/gallery-view.jsx | 150 +- .../tinymce/plugins/wpcom-view/plugin.js | 1741 +- .../plugins/wpcom-view/resizable-view.jsx | 104 +- .../tinymce/plugins/wpcom-view/views.js | 156 +- .../wpcom-view/views/contact-form/index.jsx | 62 +- .../views/contact-form/preview-fields.jsx | 92 +- .../views/contact-form/preview-fieldset.jsx | 20 +- .../views/contact-form/preview-legend.jsx | 10 +- .../views/contact-form/preview-required.jsx | 18 +- .../plugins/wpcom-view/views/embed/index.js | 224 +- .../plugins/wpcom-view/views/embed/view.jsx | 203 +- .../plugins/wpcom-view/views/video/index.js | 28 +- .../plugins/wpcom-view/views/video/view.jsx | 49 +- .../tinymce/plugins/wpcom/plugin.js | 1381 +- .../tinymce/plugins/wpcom/test/utils.js | 55 +- .../tinymce/plugins/wpcom/wpcom-utils.js | 14 +- .../tinymce/plugins/wpeditimage/plugin.js | 1429 +- .../tinymce/plugins/wplink/dialog.jsx | 669 +- .../tinymce/plugins/wplink/plugin.js | 368 +- .../tinymce/plugins/wptextpattern/plugin.js | 569 +- .../components/title-format-editor/index.jsx | 679 +- .../components/title-format-editor/parser.js | 146 +- .../components/title-format-editor/token.jsx | 21 +- .../components/token-field/docs/example.jsx | 219 +- client/components/token-field/index.jsx | 1045 +- .../token-field/suggestions-list.jsx | 271 +- client/components/token-field/test/index.jsx | 933 +- .../token-field/test/lib/fixtures.js | 98 +- .../test/lib/token-field-wrapper.jsx | 86 +- client/components/token-field/token-input.jsx | 103 +- client/components/token-field/token.jsx | 122 +- client/components/tooltip/docs/example.jsx | 151 +- client/components/tooltip/index.jsx | 86 +- .../components/track-input-changes/index.jsx | 100 +- .../track-input-changes/test/index.jsx | 202 +- .../credit-card-number-input/index.jsx | 20 +- .../upgrades/google-apps/dialog/index.jsx | 468 +- .../google-apps/dialog/product-details.jsx | 58 +- .../upgrades/google-apps/dialog/users.jsx | 256 +- .../components/upgrades/google-apps/index.jsx | 121 +- client/components/user/index.jsx | 35 +- client/components/version/docs/example.jsx | 25 +- client/components/version/index.jsx | 45 +- .../components/vertical-menu/docs/example.jsx | 22 +- client/components/vertical-menu/index.jsx | 74 +- .../vertical-menu/items/social-item.jsx | 77 +- client/components/vertical-nav/index.jsx | 18 +- client/components/vertical-nav/item/index.jsx | 91 +- client/components/virtual-list/index.jsx | 379 +- client/components/web-preview/index.jsx | 434 +- client/components/web-preview/toolbar.jsx | 209 +- .../web-preview/with-preview-props.jsx | 50 +- client/components/wordpress-logo/index.jsx | 46 +- .../components/wpadmin-auto-login/index.jsx | 72 +- client/config/index.js | 9 +- client/controller/index.node.js | 12 +- client/controller/index.web.js | 107 +- client/controller/shared.js | 41 +- client/devdocs/controller.js | 283 +- client/devdocs/design/blocks.jsx | 159 +- client/devdocs/design/index.jsx | 240 +- client/devdocs/design/search-collection.jsx | 108 +- client/devdocs/design/typography.jsx | 150 +- client/devdocs/doc.jsx | 185 +- client/devdocs/docs-example/index.jsx | 113 +- client/devdocs/docs-example/test/index.jsx | 182 +- client/devdocs/docs-example/util.js | 58 +- client/devdocs/docs-example/wrapper.jsx | 66 +- client/devdocs/docs-selectors/index.jsx | 28 +- client/devdocs/docs-selectors/param-type.jsx | 28 +- client/devdocs/docs-selectors/result.jsx | 91 +- client/devdocs/docs-selectors/search.jsx | 100 +- client/devdocs/docs-selectors/single.jsx | 89 +- client/devdocs/form-state-examples/index.jsx | 72 +- client/devdocs/index.js | 32 +- client/devdocs/main.jsx | 335 +- client/devdocs/service.js | 39 +- client/devdocs/sidebar.jsx | 157 +- client/devdocs/test/doc.jsx | 80 +- client/devdocs/welcome.jsx | 35 +- client/dispatcher/index.js | 35 +- client/extensions/hello-dolly/index.js | 91 +- client/extensions/index.js | 9 +- client/extensions/sensei/index.js | 24 +- client/extensions/woocommerce/index.js | 27 +- client/extensions/wp-job-manager/index.js | 24 +- .../wp-super-cache/components/easy.jsx | 137 +- .../wp-super-cache/components/navigation.jsx | 115 +- client/extensions/wp-super-cache/constants.js | 14 +- .../extensions/wp-super-cache/controller.js | 75 +- client/extensions/wp-super-cache/index.js | 4 +- client/extensions/wp-super-cache/main.jsx | 56 +- .../community-translator/invitation-utils.js | 270 +- .../community-translator/invitation.jsx | 148 +- .../layout/community-translator/launcher.jsx | 163 +- client/layout/error.jsx | 94 +- .../config-elements/button-row.js | 10 +- .../config-elements/combine-tours.js | 29 +- .../guided-tours/config-elements/continue.js | 166 +- .../guided-tours/config-elements/link-quit.js | 65 +- .../guided-tours/config-elements/link.js | 26 +- .../guided-tours/config-elements/make-tour.js | 117 +- .../guided-tours/config-elements/next.js | 42 +- .../guided-tours/config-elements/quit.js | 46 +- .../guided-tours/config-elements/step.js | 447 +- .../guided-tours/config-elements/tour.js | 38 +- client/layout/guided-tours/config-parsing.js | 43 +- client/layout/guided-tours/config.js | 10 +- client/layout/guided-tours/context-types.js | 28 +- client/layout/guided-tours/index.js | 170 +- client/layout/guided-tours/positioning.js | 264 +- .../tours/design-showcase-welcome-tour.js | 188 +- .../tours/editor-insert-menu-tour.js | 116 +- .../tours/gdocs-integration-tour.js | 55 +- client/layout/guided-tours/tours/main-tour.js | 337 +- .../guided-tours/tours/site-title-tour.js | 228 +- .../tours/theme-sheet-welcome-tour.js | 235 +- .../tours/tutorial-site-preview-tour.js | 134 +- client/layout/guided-tours/wait.js | 33 +- client/layout/index.jsx | 353 +- client/layout/logged-out.jsx | 79 +- client/layout/masterbar/drafts.jsx | 206 +- client/layout/masterbar/item.jsx | 91 +- client/layout/masterbar/logged-in.jsx | 309 +- client/layout/masterbar/logged-out.jsx | 73 +- client/layout/masterbar/masterbar.jsx | 10 +- client/layout/masterbar/notifications.jsx | 242 +- client/layout/masterbar/publish.jsx | 151 +- client/layout/nux-welcome/index.js | 67 +- client/layout/nux-welcome/welcome-message.jsx | 183 +- client/layout/offline-status/index.jsx | 20 +- client/layout/sidebar/button.jsx | 68 +- client/layout/sidebar/footer.jsx | 20 +- client/layout/sidebar/heading.jsx | 4 +- client/layout/sidebar/index.jsx | 36 +- client/layout/sidebar/item.jsx | 76 +- client/layout/sidebar/menu.jsx | 4 +- client/layout/sidebar/region.jsx | 4 +- client/lib/abtest/active-tests.js | 88 +- client/lib/abtest/index.js | 355 +- client/lib/abtest/test-helper/Test.jsx | 54 +- client/lib/abtest/test-helper/TestList.jsx | 36 +- client/lib/abtest/test-helper/index.js | 30 +- client/lib/abtest/test/index.js | 288 +- client/lib/accept/dialog.jsx | 97 +- client/lib/accept/index.js | 47 +- client/lib/accept/test/index.js | 89 +- client/lib/accessible-focus/index.js | 35 +- client/lib/account-password-data/index.js | 142 +- client/lib/ads/actions.js | 165 +- client/lib/ads/earnings-store.js | 97 +- client/lib/ads/settings-store.js | 166 +- client/lib/ads/test/lib/mock-actions.js | 42 +- client/lib/ads/test/lib/mock-earnings.js | 56 +- client/lib/ads/test/lib/mock-settings.js | 30 +- client/lib/ads/test/lib/mock-site.js | 58 +- client/lib/ads/test/stores.js | 96 +- client/lib/ads/tos-store.js | 140 +- client/lib/ads/utils.js | 40 +- client/lib/analytics/ad-tracking.js | 1131 +- client/lib/analytics/index.js | 686 +- .../lib/analytics/page-view-tracker/index.jsx | 88 +- .../page-view-tracker/test/index.jsx | 48 +- client/lib/analytics/super-props.js | 50 +- client/lib/analytics/test/config/index.js | 10 +- client/lib/analytics/test/index.js | 146 +- .../test/lib/analytics/ad-tracking.js | 4 +- .../analytics/test/lib/load-script/index.js | 10 +- .../analytics/track-component-view/index.jsx | 51 +- client/lib/apple-pay/index.js | 34 +- .../lib/application-passwords-data/index.js | 136 +- client/lib/auth-code-request-store/actions.js | 46 +- .../lib/auth-code-request-store/constants.js | 16 +- client/lib/auth-code-request-store/index.js | 99 +- .../lib/auth-code-request-store/test/index.js | 122 +- client/lib/automated-transfer/index.js | 62 +- client/lib/cart-values/cart-items.js | 801 +- client/lib/cart-values/index.js | 173 +- client/lib/cart-values/test/index.js | 232 +- .../lib/cart-values/test/lib/user-settings.js | 14 +- client/lib/cart-values/test/lib/user.js | 10 +- client/lib/cart/store/cart-analytics.js | 27 +- client/lib/cart/store/cart-synchronizer.js | 311 +- client/lib/cart/store/index.js | 216 +- .../lib/cart/store/test/cart-synchronizer.js | 145 +- .../lib/cart/store/test/fake-wpcom/index.js | 67 +- .../lib/cart/store/test/lib/user-settings.js | 14 +- client/lib/cart/store/test/lib/user.js | 10 +- client/lib/catch-js-errors/index.js | 185 +- client/lib/catch-js-errors/log.js | 16 +- client/lib/checkout/index.js | 32 +- .../lib/connected-applications-data/index.js | 134 +- client/lib/countries-list/index.js | 128 +- client/lib/create-config/index.js | 67 +- client/lib/create-config/test/index.js | 144 +- client/lib/create-selector/index.js | 93 +- client/lib/create-selector/test/index.js | 497 +- client/lib/credit-card-details/index.js | 11 +- client/lib/credit-card-details/masking.js | 119 +- client/lib/credit-card-details/test/index.js | 144 +- .../credit-card-details/test/validation.js | 84 +- client/lib/credit-card-details/validation.js | 281 +- client/lib/css-hot-reload/index.js | 98 +- client/lib/css-safe-url/index.js | 6 +- client/lib/css-safe-url/test/index.js | 10 +- client/lib/data-poller/index.js | 93 +- client/lib/data-poller/poller.js | 144 +- client/lib/deep-pick/index.js | 14 +- client/lib/deep-pick/test/index.js | 46 +- client/lib/design-preview/index.js | 8 +- .../lib/design-preview/updaters/site-title.js | 24 +- client/lib/desktop/index.js | 297 +- client/lib/detect-history-navigation/index.js | 18 +- client/lib/deterministic-stringify/index.js | 55 +- .../lib/deterministic-stringify/test/index.js | 88 +- client/lib/devices/index.js | 64 +- client/lib/directly/index.js | 113 +- client/lib/directly/test/index.js | 284 +- client/lib/domains/assembler.js | 87 +- client/lib/domains/constants.js | 116 +- client/lib/domains/dns/index.js | 314 +- client/lib/domains/dns/reducer.js | 267 +- client/lib/domains/dns/store.js | 8 +- client/lib/domains/dns/test/data/index.js | 16 +- client/lib/domains/dns/test/index.js | 26 +- client/lib/domains/dns/test/reducer.js | 102 +- client/lib/domains/email-forwarding/index.js | 42 +- .../lib/domains/email-forwarding/reducer.js | 147 +- client/lib/domains/email-forwarding/store.js | 10 +- .../email-forwarding/test/data/index.js | 16 +- .../domains/email-forwarding/test/reducer.js | 86 +- .../domains/email-forwarding/test/store.js | 176 +- client/lib/domains/google-apps-users/index.js | 104 +- client/lib/domains/index.js | 205 +- client/lib/domains/nameservers/index.js | 34 +- client/lib/domains/nameservers/reducer.js | 83 +- client/lib/domains/nameservers/store.js | 8 +- client/lib/domains/nameservers/test/store.js | 135 +- client/lib/domains/reducer.js | 205 +- .../registration/availability-messages.js | 213 +- client/lib/domains/site-redirect/reducer.js | 173 +- client/lib/domains/site-redirect/store.js | 14 +- client/lib/domains/store.js | 4 +- client/lib/domains/test/assembler.js | 158 +- client/lib/domains/utils.js | 51 +- .../lib/domains/wapi-domain-info/assembler.js | 12 +- .../lib/domains/wapi-domain-info/reducer.js | 133 +- client/lib/domains/wapi-domain-info/store.js | 8 +- client/lib/domains/whois/assembler.js | 51 +- client/lib/domains/whois/constants.js | 6 +- .../whois/protected-contact-information.js | 106 +- client/lib/domains/whois/reducer.js | 87 +- client/lib/domains/whois/store.js | 8 +- client/lib/domains/whois/test/assembler.js | 257 +- client/lib/domains/whois/test/store.js | 244 +- client/lib/domains/whois/utils.js | 12 +- client/lib/email-followers/actions.js | 103 +- client/lib/email-followers/store.js | 298 +- .../email-followers/test/lib/mock-actions.js | 76 +- .../test/lib/mock-email-followers.js | 30 +- .../test/lib/mock-more-email-followers.js | 30 +- .../lib/email-followers/test/lib/mock-site.js | 58 +- client/lib/email-followers/test/store.js | 146 +- client/lib/embed-frame-markup/index.jsx | 80 +- client/lib/embed-frame-markup/test/index.jsx | 64 +- client/lib/embeds/actions.js | 78 +- client/lib/embeds/list-store.js | 112 +- client/lib/embeds/store.js | 95 +- client/lib/feed-lookup/index.js | 52 +- client/lib/feed-post-store/actions.js | 167 +- client/lib/feed-post-store/constants.js | 14 +- client/lib/feed-post-store/display-types.js | 22 +- client/lib/feed-post-store/index.js | 498 +- client/lib/feed-post-store/post-fetcher.js | 118 +- client/lib/feed-post-store/test/index.js | 305 +- .../test/lib/post-normalizer.js | 21 +- client/lib/feed-post-store/test/lib/wp.js | 22 +- client/lib/feed-store/actions.js | 45 +- client/lib/feed-store/constants.js | 18 +- client/lib/feed-store/index.js | 187 +- client/lib/feed-store/test/index.js | 142 +- client/lib/feed-store/test/lib/formatting.js | 6 +- client/lib/feed-stream-store/actions.js | 314 +- client/lib/feed-stream-store/constants.js | 28 +- .../feed-stream-store/feed-stream-cache.js | 32 +- client/lib/feed-stream-store/feed-stream.js | 1036 +- client/lib/feed-stream-store/index.js | 500 +- client/lib/feed-stream-store/paged-stream.js | 553 +- client/lib/feed-stream-store/post-key.js | 100 +- client/lib/feed-stream-store/test/index.js | 669 +- .../test/lib/analytics/index.js | 4 +- .../feed-stream-store/test/lib/data-poller.js | 4 +- .../test/lib/post-normalizer.js | 21 +- client/lib/feed-stream-store/test/lib/wp.js | 26 +- client/lib/follow-list/index.js | 29 +- client/lib/follow-list/site.js | 53 +- client/lib/follow-list/test/index.js | 166 +- client/lib/follow-list/test/lib/wp.js | 40 +- client/lib/followers/actions.js | 101 +- client/lib/followers/store.js | 304 +- client/lib/followers/test/lib/mock-actions.js | 76 +- client/lib/followers/test/lib/mock-site.js | 58 +- .../test/lib/mock-wpcom-followers1.js | 42 +- .../test/lib/mock-wpcom-followers2.js | 42 +- client/lib/followers/test/store.js | 146 +- .../form-state/examples/async-initialize.jsx | 119 +- .../form-state/examples/sync-initialize.jsx | 96 +- client/lib/form-state/index.js | 624 +- .../lib/form-state/store/async-initialize.js | 68 +- client/lib/form-state/store/core.js | 32 +- client/lib/form-state/store/index.js | 111 +- .../lib/form-state/store/sync-initialize.js | 38 +- client/lib/form-state/test/index.js | 273 +- client/lib/format-currency/index.js | 188 +- client/lib/format-currency/test/index.js | 295 +- .../lib/formatting/decode-entities/browser.js | 24 +- client/lib/formatting/decode-entities/node.js | 2 +- client/lib/formatting/index.js | 623 +- client/lib/formatting/test/index.js | 357 +- client/lib/geocoding/index.js | 21 +- client/lib/geocoding/test/index.js | 44 +- client/lib/google-apps/index.js | 8 +- client/lib/happychat/connection.js | 148 +- client/lib/help-search/actions.js | 36 +- client/lib/help-search/constants.js | 8 +- client/lib/help-search/store.js | 36 +- .../lib/help-search/test/lib/mock-actions.js | 12 +- .../help-search/test/lib/mock-help-links.js | 50 +- client/lib/help-search/test/store.js | 44 +- client/lib/highlight/index.js | 132 +- client/lib/highlight/test/index.js | 108 +- client/lib/human-date/index.js | 90 +- client/lib/i18n-utils/browser.js | 7 +- client/lib/i18n-utils/node.js | 6 +- client/lib/i18n-utils/switch-locale.js | 42 +- client/lib/i18n-utils/test/utils.js | 125 +- client/lib/i18n-utils/utils.js | 56 +- client/lib/importer/actions.js | 334 +- client/lib/importer/common.js | 120 +- client/lib/importer/store.js | 348 +- client/lib/importer/test/api-interaction.js | 76 +- client/lib/infinite-list/actions.js | 93 +- client/lib/infinite-list/positions-store.js | 62 +- client/lib/infinite-list/scroll-store.js | 40 +- client/lib/inflight/index.js | 42 +- client/lib/inflight/test/index.js | 152 +- client/lib/interval/index.js | 176 +- client/lib/interval/runner.js | 115 +- client/lib/interval/test/component.jsx | 176 +- client/lib/interval/test/runner.js | 217 +- client/lib/invites/actions.js | 371 +- client/lib/invites/constants.js | 34 +- .../reducers/invites-accept-validation.js | 69 +- .../reducers/invites-create-validation.js | 28 +- client/lib/invites/reducers/invites-list.js | 47 +- client/lib/invites/reducers/invites-sent.js | 28 +- .../test/invites-create-validation.js | 77 +- .../stores/invites-accept-validation.js | 8 +- .../stores/invites-create-validation.js | 8 +- client/lib/invites/stores/invites-list.js | 4 +- client/lib/invites/stores/invites-sent.js | 6 +- .../lib/invites/stores/test/invites-list.js | 129 +- client/lib/keyboard-shortcuts/global.js | 98 +- client/lib/keyboard-shortcuts/index.js | 216 +- client/lib/keyboard-shortcuts/key-bindings.js | 325 +- client/lib/keyboard-shortcuts/menu.jsx | 221 +- client/lib/keyboard-shortcuts/test/index.js | 36 +- .../keyboard-shortcuts/test/key-bindings.js | 72 +- .../test/lib/mixins/i18n.js | 11 +- client/lib/like-store/actions.js | 161 +- client/lib/like-store/like-store.js | 347 +- client/lib/like-store/test/index.js | 440 +- client/lib/like-store/test/lib/wp.js | 8 +- client/lib/like-store/utils.js | 12 +- client/lib/load-script/index.js | 135 +- client/lib/local-list/index.js | 69 +- client/lib/local-list/test/index.js | 310 +- client/lib/local-storage/index.js | 80 +- client/lib/local-storage/test/index.js | 84 +- client/lib/locale-suggestions/actions.js | 21 +- client/lib/locale-suggestions/index.js | 45 +- client/lib/localforage/index.js | 72 +- client/lib/localforage/localforage-bypass.js | 387 +- .../localforage/test/localforage-bypass.js | 274 +- client/lib/media-serialization/constants.js | 20 +- .../create-element-from-string.js | 24 +- .../lib/media-serialization/detect-format.js | 36 +- client/lib/media-serialization/index.js | 6 +- .../lib/media-serialization/strategies/api.js | 43 +- .../lib/media-serialization/strategies/dom.js | 72 +- .../media-serialization/strategies/object.js | 4 +- .../strategies/shortcode.js | 78 +- .../media-serialization/strategies/string.js | 48 +- .../media-serialization/strategies/unknown.js | 12 +- client/lib/media-serialization/test/index.js | 276 +- client/lib/media/actions.js | 506 +- client/lib/media/constants.js | 308 +- client/lib/media/library-selected-store.js | 212 +- client/lib/media/list-store.js | 430 +- client/lib/media/store.js | 216 +- client/lib/media/test/actions.js | 823 +- .../lib/media/test/library-selected-store.js | 277 +- client/lib/media/test/list-store.js | 690 +- client/lib/media/test/store.js | 326 +- client/lib/media/test/utils.js | 1288 +- client/lib/media/test/validation-store.js | 675 +- client/lib/media/utils.js | 700 +- client/lib/media/validation-store.js | 285 +- client/lib/menu-data/menu-data.js | 1387 +- client/lib/menu-data/test/fixtures/index.js | 112 +- client/lib/menu-data/test/lib/analytics.js | 12 +- client/lib/menu-data/test/lib/mixins/i18n.js | 7 +- client/lib/menu-data/test/lib/sites-list.js | 12 +- client/lib/menu-data/test/lib/wp.js | 20 +- client/lib/menu-data/test/menu-data.js | 1076 +- client/lib/mixins/analytics/index.js | 1848 ++- client/lib/mixins/close-on-esc/index.js | 72 +- client/lib/mixins/data-observe/index.js | 102 +- client/lib/mixins/data-observe/test/index.js | 203 +- client/lib/mixins/dirty-linked-state/index.js | 30 +- .../mixins/dirty-linked-state/test/index.js | 112 +- client/lib/mixins/emitter/index.js | 15 +- client/lib/mixins/infinite-scroll/index.js | 111 +- .../lib/mixins/observe-window-resize/index.js | 20 +- client/lib/mixins/pageable/index.js | 195 +- client/lib/mixins/pageable/test/index.js | 238 +- client/lib/mixins/render-visualizer/index.js | 488 +- client/lib/mixins/searchable/index.js | 84 +- client/lib/mixins/searchable/test/index.js | 188 +- client/lib/mixins/trap-focus/index.js | 107 +- .../lib/mixins/update-post-status/index.jsx | 368 +- client/lib/mixins/url-search/build-url.js | 21 +- client/lib/mixins/url-search/index.js | 89 +- .../lib/mixins/url-search/test/build-url.js | 56 +- client/lib/network-connection/index.js | 194 +- client/lib/network-connection/test/index.js | 90 +- .../notification-settings-store/actions.js | 93 +- .../notification-settings-store/constants.js | 14 +- .../lib/notification-settings-store/index.js | 95 +- .../notification-settings-store/test/index.js | 508 +- .../toggle-state.js | 59 +- client/lib/oauth-store/actions.js | 84 +- client/lib/oauth-store/constants.js | 18 +- client/lib/oauth-store/index.js | 101 +- client/lib/oauth-store/test/index.js | 221 +- client/lib/oauth-token/index.js | 34 +- client/lib/olark-api/index.js | 4 +- client/lib/olark-api/vendor-olark.js | 195 +- client/lib/olark-events/index.js | 114 +- client/lib/olark-events/test/index.js | 54 +- client/lib/olark-events/test/mock/olark.js | 4 +- client/lib/olark-store/actions.js | 167 +- client/lib/olark-store/constants.js | 20 +- client/lib/olark-store/index.js | 85 +- client/lib/olark-store/test/index.js | 24 +- client/lib/olark/index.js | 819 +- client/lib/path-to-section/index.js | 19 +- client/lib/path-to-section/test/index.js | 49 +- client/lib/paths/index.js | 63 +- client/lib/paths/test/index.js | 72 +- client/lib/paygate-loader/index.js | 37 +- client/lib/people/actions.js | 16 +- client/lib/people/log-store.js | 244 +- client/lib/people/test/fixtures/actions.js | 70 +- client/lib/people/test/fixtures/site.js | 58 +- client/lib/people/test/log-store.js | 200 +- client/lib/perfmon/index.js | 268 +- client/lib/phone-validation/index.jsx | 78 +- client/lib/phone-validation/test/index.jsx | 75 +- client/lib/plans/constants.js | 1518 +- client/lib/plans/index.js | 232 +- client/lib/plans/utils.js | 7 +- client/lib/plugins/actions.js | 1030 +- client/lib/plugins/log-store.js | 330 +- client/lib/plugins/notices.jsx | 1816 ++- client/lib/plugins/store.js | 802 +- client/lib/plugins/test/actions.js | 215 +- client/lib/plugins/test/fixtures/actions.js | 569 +- .../lib/plugins/test/fixtures/multi-site.js | 136 +- .../plugins/test/fixtures/plugins-updated.js | 68 +- client/lib/plugins/test/fixtures/plugins.js | 120 +- client/lib/plugins/test/fixtures/site.js | 72 +- .../plugins/test/fixtures/updated-plugin.js | 22 +- client/lib/plugins/test/log-store.js | 32 +- client/lib/plugins/test/mocks/mixins/i18n.js | 7 +- client/lib/plugins/test/mocks/sites-list.js | 22 +- client/lib/plugins/test/mocks/wp.js | 2 +- client/lib/plugins/test/mocks/wpcom.js | 199 +- client/lib/plugins/test/store.js | 813 +- client/lib/plugins/test/utils.js | 364 +- client/lib/plugins/utils.js | 417 +- client/lib/plugins/wporg-data/actions.js | 164 +- client/lib/plugins/wporg-data/list-store.js | 258 +- client/lib/plugins/wporg-data/test/actions.js | 103 +- .../wporg-data/test/fixtures/actions.js | 145 +- .../lib/plugins/wporg-data/test/list-store.js | 488 +- .../plugins/wporg-data/test/mocks/actions.js | 4 +- .../wporg-data/test/mocks/local-store.js | 18 +- .../plugins/wporg-data/test/mocks/store.js | 4 +- .../plugins/wporg-data/test/mocks/wporg.js | 51 +- client/lib/popup-monitor/index.js | 84 +- client/lib/popup-monitor/test/index.js | 42 +- client/lib/post-metadata/index.js | 132 +- client/lib/post-metadata/test/index.js | 304 +- client/lib/post-normalizer/index.js | 141 +- .../rule-add-discover-properties.js | 26 +- .../rule-content-detect-media.js | 204 +- .../rule-content-detect-polls.js | 52 +- .../rule-content-disable-autoplay.js | 67 +- .../rule-content-make-embeds-safe.js | 66 +- .../rule-content-make-images-safe.js | 123 +- ...ule-content-remove-elements-by-selector.js | 48 +- .../rule-content-remove-styles.js | 40 +- .../rule-create-better-excerpt.js | 148 +- .../post-normalizer/rule-decode-entities.js | 56 +- .../post-normalizer/rule-keep-valid-images.js | 30 +- .../rule-make-site-id-safe-for-api.js | 10 +- .../rule-pick-canonical-image.js | 46 +- .../rule-pick-canonical-media.js | 79 +- .../post-normalizer/rule-pick-primary-tag.js | 18 +- .../post-normalizer/rule-prevent-widows.js | 14 +- .../rule-safe-image-properties.js | 44 +- client/lib/post-normalizer/rule-strip-html.js | 20 +- .../rule-wait-for-images-to-load.js | 242 +- .../post-normalizer/rule-with-content-dom.js | 30 +- client/lib/post-normalizer/test/index.js | 2038 +-- .../post-normalizer/test/lib/mixins/i18n.js | 7 +- .../test/lib/safe-image-url.js | 14 +- client/lib/post-normalizer/utils.js | 304 +- client/lib/posts/actions.js | 871 +- client/lib/posts/post-content-images-store.js | 95 +- client/lib/posts/post-counts-store.js | 291 +- client/lib/posts/post-edit-store.js | 695 +- client/lib/posts/post-list-cache-store.js | 282 +- client/lib/posts/post-list-store-factory.js | 16 +- client/lib/posts/post-list-store.js | 797 +- client/lib/posts/posts-store.js | 97 +- client/lib/posts/stats.js | 168 +- client/lib/posts/test/actions.js | 498 +- client/lib/posts/test/post-edit-store.js | 1581 +- client/lib/posts/test/post-list-store.js | 712 +- client/lib/posts/test/utils.js | 473 +- client/lib/posts/utils.js | 446 +- client/lib/preferences/actions.js | 140 +- client/lib/preferences/constants.js | 4 +- client/lib/preferences/store.js | 78 +- client/lib/preferences/test/actions.js | 383 +- client/lib/preferences/test/store.js | 168 +- client/lib/products-list/index.js | 96 +- client/lib/products-values/index.js | 520 +- client/lib/products-values/sort.js | 59 +- client/lib/promises/index.js | 7 +- client/lib/protect-form/index.jsx | 110 +- client/lib/purchases/assembler.js | 146 +- client/lib/purchases/index.js | 322 +- client/lib/purchases/reducer.js | 229 +- client/lib/purchases/test/assembler.js | 70 +- client/lib/purchases/test/data/index.js | 130 +- client/lib/purchases/test/index.js | 96 +- client/lib/query-manager/index.js | 534 +- client/lib/query-manager/key.js | 68 +- client/lib/query-manager/media/constants.js | 20 +- client/lib/query-manager/media/index.js | 154 +- client/lib/query-manager/media/key.js | 8 +- client/lib/query-manager/media/test/index.js | 693 +- .../lib/query-manager/paginated/constants.js | 10 +- client/lib/query-manager/paginated/index.js | 302 +- client/lib/query-manager/paginated/key.js | 16 +- .../lib/query-manager/paginated/test/index.js | 592 +- .../lib/query-manager/paginated/test/key.js | 44 +- client/lib/query-manager/post/constants.js | 24 +- client/lib/query-manager/post/index.js | 229 +- client/lib/query-manager/post/key.js | 23 +- client/lib/query-manager/post/test/index.js | 1669 +- client/lib/query-manager/post/test/key.js | 68 +- client/lib/query-manager/term/constants.js | 18 +- client/lib/query-manager/term/index.js | 56 +- client/lib/query-manager/term/key.js | 23 +- client/lib/query-manager/term/test/index.js | 253 +- client/lib/query-manager/term/test/key.js | 68 +- client/lib/query-manager/test/index.js | 738 +- client/lib/query-manager/test/key.js | 112 +- client/lib/query-manager/theme/constants.js | 12 +- client/lib/query-manager/theme/index.js | 9 +- client/lib/query-manager/theme/key.js | 23 +- client/lib/query-manager/theme/test/index.js | 46 +- client/lib/query-manager/theme/test/key.js | 68 +- client/lib/react-helpers/index.js | 35 +- client/lib/react-pass-to-children/index.js | 30 +- .../lib/react-pass-to-children/test/index.js | 143 +- client/lib/react-smart-set-state/index.js | 22 +- .../actions.js | 108 +- .../constants.js | 30 +- .../index.js | 474 +- .../test/index.js | 236 +- .../lib/reader-feed-subscriptions/actions.js | 373 +- .../reader-feed-subscriptions/constants.js | 36 +- .../lib/reader-feed-subscriptions/helper.js | 12 +- client/lib/reader-feed-subscriptions/index.js | 760 +- .../reader-feed-subscriptions/test/index.js | 697 +- client/lib/reader-lists/actions.js | 317 +- client/lib/reader-lists/constants.js | 26 +- client/lib/reader-lists/lists.js | 179 +- client/lib/reader-lists/subscriptions.js | 226 +- .../actions.js | 156 +- .../constants.js | 36 +- .../reader-post-email-subscriptions/index.js | 576 +- .../test/index.js | 426 +- client/lib/reader-post-flux-adapter/index.js | 127 +- client/lib/reader-site-store/actions.js | 43 +- client/lib/reader-site-store/constants.js | 20 +- client/lib/reader-site-store/index.js | 205 +- client/lib/reader-site-store/test/index.js | 319 +- client/lib/recommended-sites-store/actions.js | 96 +- client/lib/recommended-sites-store/store.js | 119 +- .../recommended-sites-store/test/actions.js | 313 +- .../lib/recommended-sites-store/test/store.js | 114 +- client/lib/resize-image-url/index.js | 84 +- client/lib/resize-image-url/test/index.js | 338 +- client/lib/route/add-query-args.js | 42 +- client/lib/route/index.js | 21 +- client/lib/route/legacy-routes.js | 38 +- client/lib/route/normalize.js | 21 +- client/lib/route/page-notifier.js | 34 +- client/lib/route/path.js | 188 +- client/lib/route/redirect.js | 24 +- client/lib/route/test/index.js | 971 +- client/lib/route/test/legacy-routes.js | 154 +- client/lib/route/trailingslashit.js | 4 +- client/lib/route/untrailingslashit.js | 10 +- client/lib/rubberband-scroll-disable/index.js | 33 +- client/lib/safe-image-url/index.js | 32 +- client/lib/safe-image-url/test/index.js | 258 +- client/lib/safe-protocol-url/index.js | 45 +- client/lib/safe-protocol-url/test/index.js | 94 +- client/lib/scroll-into-viewport/index.js | 28 +- client/lib/scroll-to/index.js | 96 +- client/lib/scroll-to/test/index.js | 70 +- client/lib/service-worker/index.js | 13 +- client/lib/service-worker/service-worker.js | 140 +- client/lib/shortcode/index.js | 303 +- client/lib/shortcode/test/index.js | 492 +- client/lib/shortcodes/actions.js | 24 +- client/lib/shortcodes/constants.js | 10 +- client/lib/shortcodes/store.js | 162 +- client/lib/siftscience/index.js | 43 +- client/lib/signup/actions.js | 100 +- client/lib/signup/cart.js | 90 +- client/lib/signup/dependency-store.js | 90 +- client/lib/signup/flow-controller.js | 454 +- client/lib/signup/progress-store.js | 218 +- client/lib/signup/step-actions.js | 524 +- client/lib/signup/test/dependency-store.js | 76 +- client/lib/signup/test/flow-controller.js | 344 +- client/lib/signup/test/lib/user/index.js | 10 +- client/lib/signup/test/lib/wp/index.js | 12 +- client/lib/signup/test/progress-store.js | 241 +- client/lib/signup/test/signup/config/flows.js | 54 +- client/lib/signup/test/signup/config/steps.js | 110 +- client/lib/signup/themes-data.js | 522 +- client/lib/signup/themes.js | 44 +- client/lib/site/computed-attributes.js | 89 +- client/lib/site/index.js | 318 +- client/lib/site/jetpack.js | 643 +- client/lib/site/test/index.js | 132 +- client/lib/site/test/utils.js | 362 +- client/lib/site/utils.js | 351 +- client/lib/sites-list/actions.js | 120 +- client/lib/sites-list/delete-site-store.js | 76 +- client/lib/sites-list/docs/example.jsx | 38 +- client/lib/sites-list/index.js | 70 +- client/lib/sites-list/list.js | 669 +- client/lib/sites-list/log-store.js | 233 +- client/lib/sites-list/notices.js | 297 +- client/lib/sites-list/test/fixtures/data.js | 620 +- client/lib/sites-list/test/fixtures/site.js | 56 +- client/lib/sites-list/test/index.js | 216 +- client/lib/sites-list/test/log-store.js | 38 +- .../lib/sites-list/test/mocks/lib/actions.js | 50 +- client/lib/store-transactions/index.js | 408 +- client/lib/store-transactions/step-types.js | 1 - client/lib/store/index.js | 27 +- client/lib/store/test/index.js | 224 +- client/lib/string/index.js | 10 +- client/lib/string/test/index.js | 36 +- .../support-user/localstorage-bypass.js | 138 +- .../support-user/test/localstorage-bypass.js | 243 +- client/lib/text-utils/index.js | 38 +- client/lib/text-utils/test/index.js | 90 +- client/lib/ticker/index.js | 110 +- client/lib/touch-detect/index.js | 12 +- client/lib/track-form/index.jsx | 97 +- client/lib/track-scroll-page/index.js | 10 +- client/lib/transaction/store.js | 163 +- client/lib/translator-jumpstart/index.js | 530 +- client/lib/tree-convert/index.js | 130 +- .../lib/tree-convert/test/fixtures/index.js | 106 +- client/lib/tree-convert/test/index.js | 91 +- client/lib/tree-convert/tree-traverser.js | 188 +- client/lib/trophies-data/index.js | 74 +- client/lib/two-step-authorization/index.js | 321 +- client/lib/upgrades/actions/cart.js | 138 +- client/lib/upgrades/actions/checkout.js | 84 +- .../lib/upgrades/actions/domain-management.js | 1017 +- client/lib/upgrades/actions/domain-search.js | 28 +- client/lib/upgrades/actions/free-trials.js | 22 +- client/lib/upgrades/actions/index.js | 12 +- client/lib/upgrades/actions/purchases.js | 52 +- client/lib/upgrades/constants.js | 152 +- client/lib/upgrades/notices.jsx | 55 +- client/lib/url-search/index.js | 58 +- client/lib/url/index.js | 138 +- client/lib/url/support.js | 148 +- client/lib/url/test/index.js | 395 +- client/lib/user-profile-links/index.js | 157 +- client/lib/user-settings/index.js | 281 +- client/lib/user-settings/test/index.js | 48 +- .../user-settings/test/mocks/user-utils.js | 6 +- client/lib/user-settings/test/mocks/wp.js | 42 +- client/lib/user/index.js | 65 +- client/lib/user/shared-utils.js | 111 +- client/lib/user/support-user-interop.js | 172 +- client/lib/user/test/utils.js | 100 +- client/lib/user/user.js | 425 +- client/lib/user/utils.js | 120 +- client/lib/username/index.js | 137 +- client/lib/users/actions.js | 303 +- client/lib/users/store.js | 404 +- client/lib/users/test/fixtures/actions.js | 168 +- .../lib/users/test/fixtures/deleted-user.js | 94 +- client/lib/users/test/fixtures/more-users.js | 50 +- .../lib/users/test/fixtures/polling-users.js | 12 +- client/lib/users/test/fixtures/single-user.js | 18 +- client/lib/users/test/fixtures/site.js | 58 +- .../test/fixtures/updated-single-user.js | 18 +- client/lib/users/test/fixtures/users.js | 116 +- client/lib/users/test/store.js | 429 +- client/lib/version-compare/index.js | 211 +- client/lib/viewers/actions.js | 92 +- client/lib/viewers/store.js | 211 +- client/lib/viewers/test/fixtures/actions.js | 68 +- client/lib/viewers/test/fixtures/site.js | 58 +- client/lib/viewers/test/fixtures/viewers-1.js | 46 +- client/lib/viewers/test/fixtures/viewers-2.js | 46 +- client/lib/viewers/test/store.js | 256 +- client/lib/viewport/index.js | 57 +- client/lib/warn/index.js | 6 +- client/lib/wp/browser.js | 65 +- .../lib/wp/handlers/guest-sandbox-ticket.js | 67 +- .../wp/handlers/http-envelope-normalizer.js | 47 +- .../wp/handlers/test/guest-sandbox-ticket.js | 134 +- client/lib/wp/localization/index.js | 64 +- client/lib/wp/localization/test/index.js | 274 +- client/lib/wp/node.js | 8 +- client/lib/wp/support.js | 117 +- client/lib/wp/sync-handler/cache-index.js | 302 +- client/lib/wp/sync-handler/constants.js | 6 +- client/lib/wp/sync-handler/index.js | 447 +- .../lib/wp/sync-handler/test/cache-index.js | 373 +- client/lib/wp/sync-handler/test/data/index.js | 228 +- client/lib/wp/sync-handler/test/index.js | 405 +- .../wp/sync-handler/test/mock/localforage.js | 76 +- client/lib/wp/sync-handler/utils.js | 55 +- .../lib/wp/sync-handler/whitelist-handler.js | 34 +- client/lib/wpcom-undocumented/index.js | 54 +- .../lib/account-recovery-reset.js | 22 +- .../wpcom-undocumented/lib/mailing-list.js | 88 +- client/lib/wpcom-undocumented/lib/me.js | 473 +- client/lib/wpcom-undocumented/lib/site.js | 336 +- .../wpcom-undocumented/lib/undocumented.js | 2793 ++-- client/lib/wpcom-xhr-wrapper/index.js | 18 +- client/lib/wporg/index.js | 204 +- client/lib/wporg/jsonp.js | 102 +- client/lib/wrap-es6-functions/index.js | 36 +- client/lib/wrap-es6-functions/test/index.js | 74 +- client/mailing-lists/controller.js | 37 +- client/mailing-lists/index.js | 8 +- client/mailing-lists/main.jsx | 350 +- client/mailing-lists/utils.js | 56 +- client/me/account-password/index.jsx | 365 +- client/me/account/controller.js | 54 +- client/me/account/index.js | 4 +- client/me/account/main.jsx | 1295 +- client/me/action-remove/index.jsx | 19 +- client/me/application-password-item/index.jsx | 120 +- client/me/application-passwords/index.jsx | 450 +- .../billing-history/billing-history-table.jsx | 132 +- client/me/billing-history/controller.js | 38 +- client/me/billing-history/main.jsx | 74 +- client/me/billing-history/receipt.jsx | 460 +- client/me/billing-history/table-rows.js | 102 +- .../billing-history/transactions-header.jsx | 503 +- .../me/billing-history/transactions-table.jsx | 371 +- .../upcoming-charges-table.jsx | 109 +- .../me/connected-application-icon/index.jsx | 39 +- .../me/connected-application-item/index.jsx | 414 +- client/me/connected-applications/index.jsx | 296 +- client/me/constants.js | 8 +- client/me/controller.js | 196 +- client/me/event-recorder/index.js | 94 +- client/me/form-base/index.js | 146 +- client/me/get-apps/index.jsx | 180 +- client/me/happychat/index.jsx | 16 +- client/me/happychat/main.jsx | 51 +- client/me/help/chat-closure-notice/index.jsx | 86 +- .../me/help/chat-closure-notice/messages.jsx | 162 +- client/me/help/controller.js | 90 +- client/me/help/help-contact-closed/detail.jsx | 22 +- client/me/help/help-contact-closed/index.jsx | 178 +- .../help/help-contact-confirmation/index.jsx | 42 +- client/me/help/help-contact-form/index.jsx | 465 +- client/me/help/help-contact/index.jsx | 1332 +- client/me/help/help-courses/course-list.jsx | 24 +- .../help-courses/course-schedule-item.jsx | 89 +- client/me/help/help-courses/course-video.jsx | 31 +- client/me/help/help-courses/course-videos.jsx | 26 +- client/me/help/help-courses/course.jsx | 92 +- client/me/help/help-courses/courses.jsx | 80 +- client/me/help/help-courses/index.jsx | 103 +- .../help/help-happiness-engineers/index.jsx | 69 +- client/me/help/help-results/index.jsx | 50 +- client/me/help/help-results/item.jsx | 91 +- client/me/help/help-search/index.jsx | 194 +- client/me/help/help-teaser-button.jsx | 34 +- .../me/help/help-unverified-warning/index.jsx | 113 +- client/me/help/index.js | 32 +- client/me/help/main.jsx | 426 +- client/me/index.js | 45 +- client/me/next-steps/index.jsx | 398 +- client/me/next-steps/next-steps-box.jsx | 76 +- client/me/next-steps/steps.js | 253 +- .../blogs-settings/blog.jsx | 110 +- .../blogs-settings/header.jsx | 166 +- .../blogs-settings/index.jsx | 115 +- .../blogs-settings/placeholder.jsx | 72 +- .../comment-settings/index.jsx | 127 +- client/me/notification-settings/controller.js | 171 +- client/me/notification-settings/index.js | 14 +- client/me/notification-settings/main.jsx | 106 +- .../me/notification-settings/navigation.jsx | 85 +- .../push-notification-settings/index.jsx | 1204 +- .../reader-subscriptions/index.jsx | 328 +- .../settings-form/actions.jsx | 51 +- .../settings-form/constants.js | 2 +- .../settings-form/device-selector.jsx | 55 +- .../settings-form/index.jsx | 71 +- .../settings-form/labels-list.jsx | 42 +- .../settings-form/labels.jsx | 34 +- .../settings-form/locales.js | 30 +- .../settings-form/settings.jsx | 164 +- .../settings-form/stream-header.jsx | 44 +- .../settings-form/stream-options.jsx | 68 +- .../settings-form/stream-selector.jsx | 62 +- .../settings-form/stream.jsx | 118 +- .../wpcom-settings/email-category.jsx | 48 +- .../wpcom-settings/index.jsx | 274 +- client/me/profile-gravatar/index.jsx | 87 +- client/me/profile-link/index.jsx | 128 +- client/me/profile-links-add-other/index.jsx | 303 +- .../me/profile-links-add-wordpress/index.jsx | 458 +- client/me/profile-links/add-buttons.jsx | 104 +- client/me/profile-links/index.jsx | 449 +- client/me/profile/index.jsx | 243 +- client/me/purchases/add-credit-card/index.jsx | 62 +- .../cancel-privacy-protection/index.jsx | 402 +- .../me/purchases/cancel-purchase/button.jsx | 729 +- client/me/purchases/cancel-purchase/index.jsx | 315 +- .../cancel-purchase/loading-placeholder.jsx | 53 +- .../cancel-purchase/refund-information.jsx | 349 +- .../components/loading-placeholder/index.jsx | 38 +- .../purchase-card-details/index.jsx | 76 +- .../cancellation-reasons.js | 124 +- .../purchases/confirm-cancel-domain/index.jsx | 560 +- .../loading-placeholder.jsx | 51 +- client/me/purchases/controller.jsx | 331 +- .../credit-cards/credit-card-delete.jsx | 99 +- client/me/purchases/credit-cards/index.jsx | 127 +- client/me/purchases/index.js | 165 +- client/me/purchases/list/header/index.jsx | 36 +- client/me/purchases/list/index.jsx | 137 +- client/me/purchases/list/item/index.jsx | 268 +- client/me/purchases/list/site/index.jsx | 64 +- client/me/purchases/manage-purchase/index.jsx | 1396 +- client/me/purchases/paths.js | 54 +- .../payment/add-card-details/index.jsx | 94 +- .../payment/edit-card-details/index.jsx | 106 +- client/me/purchases/product-link/index.jsx | 103 +- client/me/purchases/remove-purchase/index.jsx | 789 +- client/me/purchases/test/utils.js | 106 +- client/me/purchases/titles.js | 18 +- client/me/purchases/utils.js | 116 +- client/me/reauth-required/index.jsx | 451 +- .../security-2fa-app-chooser-item/index.jsx | 227 +- .../security-2fa-backup-codes-list/index.jsx | 750 +- .../index.jsx | 312 +- client/me/security-2fa-backup-codes/index.jsx | 320 +- client/me/security-2fa-code-prompt/index.jsx | 549 +- client/me/security-2fa-disable/index.jsx | 280 +- client/me/security-2fa-enable/index.jsx | 879 +- .../me/security-2fa-initial-setup/index.jsx | 85 +- client/me/security-2fa-progress/index.jsx | 111 +- .../security-2fa-progress/progress-item.jsx | 79 +- .../security-2fa-setup-backup-codes/index.jsx | 219 +- client/me/security-2fa-setup/index.jsx | 164 +- client/me/security-2fa-sms-settings/index.jsx | 479 +- client/me/security-2fa-status/index.jsx | 74 +- .../me/security-account-recovery/buttons.jsx | 78 +- .../security-account-recovery/edit-email.jsx | 293 +- .../security-account-recovery/edit-phone.jsx | 237 +- client/me/security-account-recovery/index.jsx | 174 +- .../manage-contact.jsx | 237 +- .../recovery-email-validation-notice.jsx | 47 +- .../recovery-email.jsx | 84 +- .../recovery-phone-validation-notice.jsx | 135 +- .../recovery-phone.jsx | 88 +- client/me/security-section-nav/index.jsx | 137 +- client/me/security/controller.js | 180 +- client/me/security/index.js | 18 +- client/me/security/main.jsx | 92 +- .../sidebar-navigation/sidebar-navigation.jsx | 12 +- client/me/sidebar/index.jsx | 339 +- client/me/two-step/index.jsx | 293 +- client/my-sites/ads/controller.js | 113 +- client/my-sites/ads/form-earnings.jsx | 701 +- client/my-sites/ads/form-settings.jsx | 873 +- client/my-sites/ads/index.js | 16 +- client/my-sites/ads/main.jsx | 459 +- client/my-sites/all-sites-icon/index.jsx | 72 +- client/my-sites/all-sites/index.jsx | 118 +- client/my-sites/controller.js | 752 +- client/my-sites/current-site/index.jsx | 314 +- client/my-sites/current-site/notice.jsx | 255 +- client/my-sites/customize/actions.js | 76 +- client/my-sites/customize/controller.js | 56 +- client/my-sites/customize/index.js | 21 +- client/my-sites/customize/loading-panel.jsx | 48 +- client/my-sites/customize/main.jsx | 627 +- client/my-sites/customize/panels.js | 22 +- client/my-sites/customize/test/panels.js | 32 +- client/my-sites/design-preview/index.js | 400 +- client/my-sites/domain-tip/docs/example.jsx | 19 +- client/my-sites/domain-tip/index.jsx | 165 +- client/my-sites/draft/index.jsx | 608 +- client/my-sites/drafts/controller.js | 31 +- client/my-sites/drafts/draft-list.jsx | 299 +- client/my-sites/drafts/index.js | 21 +- client/my-sites/drafts/main.jsx | 69 +- .../export-card/advanced-settings.jsx | 107 +- .../my-sites/exporter/export-card/index.jsx | 150 +- .../export-card/post-type-options.jsx | 167 +- .../my-sites/exporter/export-card/select.jsx | 139 +- .../complete-purchase-notice.jsx | 45 +- .../guided-transfer-card/in-progress.jsx | 39 +- .../exporter/guided-transfer-card/index.jsx | 214 +- client/my-sites/exporter/index.jsx | 44 +- client/my-sites/exporter/notices.jsx | 113 +- .../feature-comparison/docs/example.jsx | 109 +- client/my-sites/feature-comparison/index.jsx | 29 +- .../guided-transfer/guided-transfer.jsx | 146 +- .../host-credentials-page/bluehost.jsx | 111 +- .../host-credentials-page/error-notice.jsx | 50 +- .../host-credentials-page/fields.jsx | 185 +- .../host-credentials-page/index.jsx | 173 +- .../host-credentials-page/pressable.jsx | 113 +- .../host-credentials-page/siteground.jsx | 111 +- .../my-sites/guided-transfer/host-select.jsx | 108 +- client/my-sites/guided-transfer/index.js | 16 +- .../guided-transfer/issues-notices.jsx | 67 +- .../transfer-unavailable-card.jsx | 138 +- .../my-sites/importer/author-mapping-item.jsx | 97 +- .../my-sites/importer/author-mapping-pane.jsx | 269 +- .../my-sites/importer/dispatcher-converter.js | 35 +- client/my-sites/importer/error-pane.jsx | 136 +- client/my-sites/importer/file-importer.jsx | 126 +- client/my-sites/importer/importer-header.jsx | 187 +- client/my-sites/importer/importer-medium.jsx | 47 +- .../my-sites/importer/importer-wordpress.jsx | 88 +- client/my-sites/importer/importing-pane.jsx | 421 +- client/my-sites/importer/uploading-pane.jsx | 261 +- client/my-sites/index.js | 4 +- client/my-sites/invites/controller.js | 107 +- client/my-sites/invites/index.js | 10 +- .../invites/invite-accept-logged-in/index.jsx | 264 +- .../invite-accept-logged-out/index.jsx | 299 +- .../my-sites/invites/invite-accept/index.jsx | 425 +- .../invites/invite-form-header/index.jsx | 505 +- .../my-sites/invites/invite-header/index.jsx | 218 +- client/my-sites/invites/utils.js | 245 +- .../jetpack-manage-error-page/index.jsx | 132 +- client/my-sites/media-library/content.jsx | 399 +- client/my-sites/media-library/drop-zone.jsx | 117 +- client/my-sites/media-library/filter-bar.jsx | 222 +- client/my-sites/media-library/filter-item.jsx | 32 +- .../media-library/filter-to-mime-prefix.js | 34 +- client/my-sites/media-library/header.jsx | 265 +- client/my-sites/media-library/index.jsx | 323 +- .../media-library/list-item-audio.jsx | 16 +- .../media-library/list-item-document.jsx | 16 +- .../media-library/list-item-file-details.jsx | 70 +- .../media-library/list-item-image.jsx | 192 +- .../media-library/list-item-video.jsx | 98 +- client/my-sites/media-library/list-item.jsx | 240 +- .../media-library/list-no-content.jsx | 109 +- .../media-library/list-no-results.jsx | 135 +- .../my-sites/media-library/list-plan-promo.js | 133 +- .../media-library/list-plan-upgrade-nudge.jsx | 63 +- client/my-sites/media-library/list.jsx | 469 +- client/my-sites/media-library/scale.jsx | 231 +- .../media-library/test/fixtures/index.js | 55 +- client/my-sites/media-library/test/list.jsx | 351 +- .../my-sites/media-library/upload-button.jsx | 107 +- client/my-sites/media-library/upload-url.jsx | 180 +- client/my-sites/media/controller.js | 56 +- client/my-sites/media/index.js | 23 +- client/my-sites/media/main.jsx | 466 +- client/my-sites/menus/controller.js | 96 +- client/my-sites/menus/index.js | 8 +- .../menus/item-options/empty-placeholder.jsx | 173 +- .../item-options/loading-placeholder.jsx | 22 +- .../menus/item-options/option-list.jsx | 188 +- .../my-sites/menus/item-options/options.jsx | 92 +- .../my-sites/menus/item-options/post-list.jsx | 65 +- client/my-sites/menus/item-options/posts.jsx | 121 +- .../menus/item-options/taxonomy-options.jsx | 138 +- .../menus/item-options/test/posts.jsx | 98 +- client/my-sites/menus/loading-placeholder.jsx | 54 +- client/my-sites/menus/location-picker.jsx | 90 +- client/my-sites/menus/main.jsx | 600 +- client/my-sites/menus/menu-delete-button.jsx | 118 +- client/my-sites/menus/menu-editable-item.jsx | 815 +- .../my-sites/menus/menu-item-drop-target.jsx | 72 +- client/my-sites/menus/menu-item-list.jsx | 911 +- .../my-sites/menus/menu-item-type-label.jsx | 27 +- client/my-sites/menus/menu-name.jsx | 229 +- .../my-sites/menus/menu-panel-back-button.jsx | 35 +- client/my-sites/menus/menu-picker.jsx | 183 +- client/my-sites/menus/menu-placeholder.jsx | 55 +- client/my-sites/menus/menu-utils.js | 25 +- client/my-sites/menus/menu.jsx | 460 +- client/my-sites/menus/menus-revert-button.jsx | 95 +- client/my-sites/menus/menus-save-button.jsx | 102 +- client/my-sites/navigation/navigation.jsx | 52 +- client/my-sites/no-results/index.jsx | 37 +- client/my-sites/pages/blog-posts-page.jsx | 192 +- client/my-sites/pages/controller.js | 94 +- client/my-sites/pages/helpers.js | 50 +- client/my-sites/pages/index.js | 19 +- client/my-sites/pages/main.jsx | 217 +- client/my-sites/pages/page-list.jsx | 495 +- client/my-sites/pages/page.jsx | 933 +- client/my-sites/pages/placeholder.jsx | 59 +- client/my-sites/paladin/controller.js | 15 +- client/my-sites/paladin/index.js | 14 +- client/my-sites/paladin/main.jsx | 37 +- client/my-sites/people/controller.js | 218 +- client/my-sites/people/delete-user/index.jsx | 564 +- .../people/edit-team-member-form/index.jsx | 647 +- .../my-sites/people/followers-list/index.jsx | 479 +- client/my-sites/people/index.js | 64 +- .../my-sites/people/invite-people/index.jsx | 709 +- client/my-sites/people/main.jsx | 130 +- .../people/people-list-item/index.jsx | 101 +- .../people-list-section-header/index.jsx | 145 +- .../my-sites/people/people-notices/index.jsx | 385 +- .../my-sites/people/people-profile/index.jsx | 351 +- .../people/people-section-nav/index.jsx | 303 +- client/my-sites/people/role-select/index.jsx | 110 +- client/my-sites/people/team-list/index.jsx | 306 +- client/my-sites/people/viewers-list/index.jsx | 345 +- client/my-sites/picker/picker.jsx | 152 +- .../plan-compare-card/docs/example.jsx | 60 +- client/my-sites/plan-compare-card/index.jsx | 114 +- client/my-sites/plan-compare-card/item.jsx | 58 +- client/my-sites/plan-features/actions.jsx | 130 +- client/my-sites/plan-features/header.jsx | 452 +- client/my-sites/plan-features/index.jsx | 963 +- client/my-sites/plan-features/item.jsx | 35 +- client/my-sites/plan-features/placeholder.jsx | 77 +- client/my-sites/plan-price/docs/example.jsx | 23 +- client/my-sites/plan-price/index.jsx | 85 +- client/my-sites/plans-features-main/index.jsx | 696 +- client/my-sites/plans/controller.jsx | 90 +- .../plans/current-plan/controller.jsx | 34 +- client/my-sites/plans/current-plan/header.jsx | 231 +- client/my-sites/plans/current-plan/index.jsx | 263 +- client/my-sites/plans/index.js | 109 +- client/my-sites/plans/main.jsx | 152 +- .../my-sites/plans/wpcom-plan-price/index.jsx | 28 +- .../plugins-wpcom/business-plugins-panel.jsx | 91 +- .../my-sites/plugins-wpcom/default-plugins.js | 366 +- client/my-sites/plugins-wpcom/index.jsx | 4 +- .../plugins-wpcom/jetpack-plugin-item.jsx | 92 +- .../plugins-wpcom/jetpack-plugins-panel.jsx | 444 +- .../my-sites/plugins-wpcom/jetpack-plugins.js | 372 +- .../plugins-wpcom/plugin-install-button.jsx | 109 +- .../my-sites/plugins-wpcom/plugin-panel.jsx | 81 +- client/my-sites/plugins-wpcom/plugin.jsx | 105 +- .../my-sites/plugins-wpcom/plugins-list.jsx | 27 +- .../plugins-wpcom/premium-plugins-panel.jsx | 95 +- .../plugins-wpcom/purchase-button.jsx | 35 +- .../plugins-wpcom/standard-plugins-panel.jsx | 120 +- client/my-sites/plugins/access-control.js | 90 +- client/my-sites/plugins/controller.js | 434 +- .../disconnect-jetpack-button.jsx | 96 +- .../disconnect-jetpack-dialog.jsx | 215 +- client/my-sites/plugins/index.js | 123 +- .../plugins/jetpack-plugins-setup/index.jsx | 1079 +- client/my-sites/plugins/main.jsx | 871 +- .../plugins/plugin-action/plugin-action.jsx | 164 +- .../plugins/plugin-action/test/index.jsx | 80 +- .../plugins/plugin-activate-toggle/index.jsx | 217 +- .../test/fixtures/index.js | 26 +- .../plugin-activate-toggle/test/index.jsx | 73 +- .../test/mocks/actions.js | 4 +- .../test/mocks/plugin-action.jsx | 10 +- .../plugin-automated-transfer/index.jsx | 287 +- .../plugin-autoupdate-toggle/index.jsx | 306 +- .../test/fixtures/index.js | 30 +- .../plugin-autoupdate-toggle/test/index.jsx | 72 +- .../test/mocks/actions.js | 6 +- .../test/mocks/plugin-action.jsx | 12 +- .../plugins/plugin-eligibility/index.jsx | 87 +- .../plugins/plugin-icon/plugin-icon.jsx | 34 +- .../plugins/plugin-information/index.jsx | 461 +- .../plugins/plugin-install-button/index.jsx | 475 +- .../plugins/plugin-item/plugin-item.jsx | 738 +- .../plugins/plugin-list-header/index.jsx | 798 +- client/my-sites/plugins/plugin-meta/index.jsx | 993 +- .../my-sites/plugins/plugin-ratings/index.jsx | 219 +- .../plugins/plugin-remove-button/index.jsx | 333 +- .../plugins/plugin-sections/index.jsx | 410 +- .../plugin-site-disabled-manage/index.jsx | 64 +- .../plugins/plugin-site-jetpack/index.jsx | 269 +- .../plugins/plugin-site-list/index.jsx | 107 +- .../plugins/plugin-site-network/index.jsx | 301 +- .../plugin-site-update-indicator/index.jsx | 165 +- .../plugins/plugin-site/plugin-site.jsx | 58 +- client/my-sites/plugins/plugin.jsx | 817 +- .../plugins/plugins-browser-item/index.jsx | 179 +- .../plugins/plugins-browser-list/index.jsx | 137 +- .../plugins/plugins-browser/index.jsx | 667 +- .../my-sites/plugins/plugins-list/index.jsx | 963 +- .../plugins-list/test/fixtures/index.js | 108 +- .../plugins/plugins-list/test/index.jsx | 164 +- client/my-sites/post-like-button/index.jsx | 20 +- .../post-relative-time-status/index.jsx | 227 +- .../my-sites/post-selector/docs/example.jsx | 96 +- client/my-sites/post-selector/index.jsx | 144 +- client/my-sites/post-selector/no-results.jsx | 59 +- client/my-sites/post-selector/search.jsx | 38 +- client/my-sites/post-selector/selector.jsx | 841 +- client/my-sites/post-type-filter/index.jsx | 246 +- .../my-sites/post-type-list/empty-content.jsx | 79 +- client/my-sites/post-type-list/index.jsx | 302 +- .../post-actions-ellipsis-menu/edit.jsx | 82 +- .../post-actions-ellipsis-menu/index.jsx | 68 +- .../post-actions-ellipsis-menu/publish.jsx | 92 +- .../post-actions-ellipsis-menu/restore.jsx | 100 +- .../post-actions-ellipsis-menu/stats.jsx | 63 +- .../post-actions-ellipsis-menu/trash.jsx | 116 +- .../post-actions-ellipsis-menu/view.jsx | 119 +- .../post-type-list/post-thumbnail.jsx | 40 +- .../post-type-post-author/index.jsx | 53 +- client/my-sites/post/post-image/index.jsx | 183 +- client/my-sites/posts/controller.js | 155 +- client/my-sites/posts/index.js | 13 +- client/my-sites/posts/main.jsx | 266 +- client/my-sites/posts/post-controls.jsx | 386 +- client/my-sites/posts/post-header.jsx | 83 +- client/my-sites/posts/post-list.jsx | 578 +- client/my-sites/posts/post-placeholder.jsx | 92 +- client/my-sites/posts/post-share.jsx | 453 +- client/my-sites/posts/post-total-views.jsx | 93 +- client/my-sites/posts/post.jsx | 638 +- client/my-sites/posts/posts-navigation.jsx | 653 +- client/my-sites/resume-editing/index.jsx | 214 +- .../my-sites/sharing/buttons/appearance.jsx | 324 +- client/my-sites/sharing/buttons/buttons.jsx | 221 +- .../my-sites/sharing/buttons/label-editor.jsx | 157 +- client/my-sites/sharing/buttons/options.jsx | 439 +- .../sharing/buttons/preview-action.jsx | 49 +- .../sharing/buttons/preview-button.jsx | 117 +- .../sharing/buttons/preview-buttons.jsx | 491 +- .../sharing/buttons/preview-placeholder.jsx | 90 +- .../sharing/buttons/preview-widget.js | 48 +- client/my-sites/sharing/buttons/preview.jsx | 402 +- client/my-sites/sharing/buttons/style.jsx | 119 +- client/my-sites/sharing/buttons/tray.jsx | 433 +- .../connections/account-dialog-account.jsx | 73 +- .../sharing/connections/account-dialog.jsx | 351 +- .../sharing/connections/connection.jsx | 412 +- .../sharing/connections/connections.jsx | 22 +- .../sharing/connections/service-action.jsx | 147 +- .../service-connected-accounts.jsx | 35 +- .../connections/service-description.jsx | 218 +- .../sharing/connections/service-example.jsx | 28 +- .../sharing/connections/service-examples.jsx | 605 +- .../connections/service-placeholder.jsx | 71 +- .../sharing/connections/service-tip.jsx | 166 +- .../my-sites/sharing/connections/service.jsx | 770 +- .../sharing/connections/services-group.jsx | 68 +- .../connections/services/eventbrite.js | 570 +- client/my-sites/sharing/controller.js | 114 +- client/my-sites/sharing/index.js | 30 +- client/my-sites/sharing/main.jsx | 160 +- .../sidebar-navigation/sidebar-navigation.jsx | 51 +- client/my-sites/sidebar/publish-menu.jsx | 446 +- client/my-sites/sidebar/sidebar.jsx | 1269 +- client/my-sites/sidebar/test/sidebar.jsx | 135 +- .../site-indicator/site-indicator.jsx | 626 +- .../site-settings/action-panel/body.jsx | 12 +- .../site-settings/action-panel/figure.jsx | 24 +- .../site-settings/action-panel/footer.jsx | 12 +- .../site-settings/action-panel/index.jsx | 12 +- .../site-settings/action-panel/title.jsx | 12 +- .../comment-display-settings/index.jsx | 122 +- .../composing/after-the-deadline.jsx | 458 +- .../composing/default-post-format.jsx | 99 +- .../site-settings/composing/index.jsx | 108 +- client/my-sites/site-settings/controller.js | 387 +- .../custom-content-types/index.jsx | 323 +- .../date-time-format/date-format-option.jsx | 110 +- .../date-time-format-options.jsx | 285 +- .../date-time-format/default-formats.js | 13 +- .../site-settings/date-time-format/index.jsx | 40 +- .../date-time-format/start-of-week-option.jsx | 53 +- .../date-time-format/time-format-option.jsx | 128 +- .../site-settings/date-time-format/utils.js | 8 +- .../delete-site-options/index.jsx | 300 +- .../delete-site-warning-dialog/index.jsx | 45 +- .../site-settings/delete-site/index.jsx | 635 +- .../my-sites/site-settings/form-analytics.jsx | 416 +- client/my-sites/site-settings/form-base.js | 301 +- .../site-settings/form-discussion.jsx | 1278 +- .../my-sites/site-settings/form-general.jsx | 1386 +- .../site-settings/form-jetpack-monitor.jsx | 448 +- .../my-sites/site-settings/form-security.jsx | 182 +- .../my-sites/site-settings/form-writing.jsx | 309 +- client/my-sites/site-settings/index.js | 130 +- .../site-settings/jetpack-dev-mode-notice.jsx | 60 +- .../jetpack-module-toggle/index.jsx | 151 +- .../site-settings/jetpack-site-stats.jsx | 334 +- .../jetpack-sync-panel/index.jsx | 373 +- client/my-sites/site-settings/main.jsx | 217 +- .../site-settings/media-settings/index.jsx | 216 +- client/my-sites/site-settings/navigation.jsx | 221 +- .../site-settings/press-this/index.jsx | 107 +- .../site-settings/press-this/link.jsx | 134 +- client/my-sites/site-settings/protect.jsx | 320 +- .../site-settings/publishing-tools/index.jsx | 337 +- .../site-settings/related-posts/index.jsx | 122 +- .../related-posts/related-content-preview.jsx | 127 +- .../my-sites/site-settings/section-export.jsx | 46 +- .../site-settings/section-general.jsx | 37 +- .../my-sites/site-settings/section-import.jsx | 242 +- .../site-settings/section-security.jsx | 72 +- .../site-settings/seo-settings/form.jsx | 1427 +- .../site-settings/seo-settings/help.jsx | 74 +- .../site-settings/seo-settings/main.jsx | 102 +- .../site-settings/site-icon-setting/index.jsx | 630 +- client/my-sites/site-settings/sso.jsx | 156 +- .../site-settings/start-over/index.jsx | 103 +- .../site-settings/subscriptions/index.jsx | 181 +- .../site-settings/taxonomies/index.jsx | 54 +- .../taxonomies/taxonomy-card.jsx | 107 +- .../theme-enhancements/index.jsx | 318 +- .../theme-setup-dialog/index.jsx | 208 +- .../theme-setup/active-theme-screenshot.jsx | 35 +- .../site-settings/theme-setup/index.jsx | 53 +- .../theme-setup/theme-setup-card.jsx | 52 +- .../theme-setup/theme-setup-placeholder.jsx | 41 +- .../site-settings/traffic/controller.js | 78 +- .../my-sites/site-settings/traffic/index.js | 17 +- .../my-sites/site-settings/traffic/main.jsx | 124 +- .../site-settings/wrap-settings-form.jsx | 422 +- client/my-sites/sites/sites.jsx | 136 +- client/my-sites/stats/all-time/index.jsx | 181 +- .../my-sites/stats/comment-follows/index.jsx | 105 +- client/my-sites/stats/controller.jsx | 939 +- client/my-sites/stats/geochart/index.jsx | 288 +- client/my-sites/stats/index.js | 184 +- client/my-sites/stats/info-panel/index.jsx | 500 +- client/my-sites/stats/most-popular/index.jsx | 167 +- client/my-sites/stats/overview.jsx | 206 +- client/my-sites/stats/pagination/index.jsx | 132 +- .../stats/pagination/pagination-page.jsx | 143 +- .../my-sites/stats/post-performance/index.jsx | 280 +- client/my-sites/stats/post-trends/day.jsx | 128 +- client/my-sites/stats/post-trends/index.jsx | 366 +- client/my-sites/stats/post-trends/month.jsx | 94 +- client/my-sites/stats/post-trends/week.jsx | 103 +- client/my-sites/stats/site.jsx | 355 +- .../my-sites/stats/stats-chart-tabs/index.jsx | 544 +- .../stats-comment-followers-page/index.jsx | 259 +- .../stats/stats-comments/comment-tab.jsx | 42 +- .../my-sites/stats/stats-comments/index.jsx | 337 +- .../my-sites/stats/stats-countries/index.jsx | 48 +- .../stats/stats-date-picker/index.jsx | 330 +- .../stats/stats-detail-months/index.jsx | 257 +- .../stats/stats-detail-weeks/index.jsx | 373 +- .../stats/stats-download-csv/index.jsx | 140 +- client/my-sites/stats/stats-error/index.jsx | 33 +- .../my-sites/stats/stats-first-view/index.jsx | 186 +- .../my-sites/stats/stats-followers/index.jsx | 395 +- .../my-sites/stats/stats-insights/index.jsx | 132 +- .../stats/stats-list/action-follow.jsx | 120 +- .../my-sites/stats/stats-list/action-link.jsx | 83 +- .../my-sites/stats/stats-list/action-page.jsx | 68 +- .../my-sites/stats/stats-list/action-spam.jsx | 130 +- client/my-sites/stats/stats-list/index.jsx | 120 +- client/my-sites/stats/stats-list/legend.jsx | 70 +- .../stats/stats-list/stats-list-item.jsx | 601 +- .../stats/stats-module/all-time-nav.jsx | 142 +- .../stats/stats-module/content-text.jsx | 26 +- client/my-sites/stats/stats-module/expand.jsx | 36 +- client/my-sites/stats/stats-module/header.jsx | 267 +- client/my-sites/stats/stats-module/index.jsx | 346 +- .../stats/stats-module/placeholder.jsx | 32 +- .../stats/stats-module/select-dropdown.jsx | 20 +- .../my-sites/stats/stats-navigation/index.jsx | 85 +- .../stats-overview-placeholder/index.jsx | 102 +- .../stats/stats-page-placeholder/index.jsx | 24 +- .../stats/stats-period-navigation/index.jsx | 74 +- .../stats/stats-post-detail/index.jsx | 325 +- .../my-sites/stats/stats-post-likes/index.jsx | 108 +- .../stats/stats-post-summary/index.jsx | 305 +- client/my-sites/stats/stats-reach/index.jsx | 116 +- .../stats/stats-site-overview/index.jsx | 145 +- client/my-sites/stats/stats-strings.js | 166 +- client/my-sites/stats/stats-summary/index.jsx | 158 +- client/my-sites/stats/stats-tabs/index.jsx | 107 +- client/my-sites/stats/stats-tabs/tab.jsx | 119 +- .../stats/stats-video-details/index.jsx | 68 +- .../stats/stats-video-summary/index.jsx | 124 +- client/my-sites/stats/stats-views/index.jsx | 147 +- client/my-sites/stats/stats-views/months.jsx | 410 +- client/my-sites/stats/summary/index.jsx | 396 +- client/my-sites/stats/toggle-info.jsx | 33 +- client/my-sites/theme/controller.jsx | 92 +- client/my-sites/theme/index.node.js | 13 +- client/my-sites/theme/index.web.js | 14 +- client/my-sites/theme/main.jsx | 1204 +- client/my-sites/theme/test/main.jsx | 157 +- .../theme/theme-download-card/index.jsx | 43 +- .../theme/themes-related-card/index.jsx | 109 +- client/my-sites/themes/controller.jsx | 198 +- .../my-sites/themes/current-theme/button.jsx | 58 +- .../my-sites/themes/current-theme/index.jsx | 147 +- client/my-sites/themes/helpers.js | 54 +- client/my-sites/themes/index.node.js | 50 +- client/my-sites/themes/index.web.js | 93 +- .../jetpack-manage-disabled-message.jsx | 105 +- .../themes/jetpack-referrer-message.jsx | 38 +- .../themes/jetpack-upgrade-message.jsx | 34 +- client/my-sites/themes/logged-out.jsx | 21 +- client/my-sites/themes/multi-site.jsx | 38 +- .../my-sites/themes/single-site-jetpack.jsx | 243 +- client/my-sites/themes/single-site-wpcom.jsx | 46 +- client/my-sites/themes/single-site.jsx | 79 +- client/my-sites/themes/test/logged-out.jsx | 220 +- client/my-sites/themes/test/theme-filters.js | 172 +- client/my-sites/themes/thanks-modal.jsx | 365 +- client/my-sites/themes/theme-filters.js | 433 +- client/my-sites/themes/theme-options.js | 337 +- client/my-sites/themes/theme-preview.jsx | 288 +- client/my-sites/themes/theme-showcase.jsx | 365 +- client/my-sites/themes/theme-upload/index.jsx | 664 +- .../themes/themes-magic-search-card/index.jsx | 623 +- .../taxonomies-config.js | 24 +- .../themes-magic-search-card/welcome.jsx | 198 +- .../themes/themes-search-card/index.jsx | 317 +- .../themes-search-card/select-dropdown.jsx | 77 +- .../themes/themes-selection-header/index.jsx | 26 +- client/my-sites/themes/themes-selection.jsx | 422 +- .../themes/themes-site-selector-modal.jsx | 194 +- client/my-sites/themes/validate-filters.js | 27 +- client/my-sites/types/controller.jsx | 22 +- client/my-sites/types/index.js | 14 +- client/my-sites/types/main.jsx | 71 +- .../types/post-type-forbidden/index.jsx | 19 +- .../types/post-type-unsupported/index.jsx | 68 +- .../my-sites/upgrade-nudge/docs/example.jsx | 47 +- client/my-sites/upgrade-nudge/index.jsx | 240 +- client/my-sites/upgrades/cart/cart-ad.jsx | 4 +- client/my-sites/upgrades/cart/cart-body.jsx | 37 +- .../cart/cart-body/loading-placeholder.jsx | 12 +- .../my-sites/upgrades/cart/cart-buttons.jsx | 106 +- client/my-sites/upgrades/cart/cart-coupon.jsx | 206 +- client/my-sites/upgrades/cart/cart-empty.jsx | 61 +- client/my-sites/upgrades/cart/cart-item.jsx | 379 +- .../cart/cart-item/loading-placeholder.jsx | 20 +- client/my-sites/upgrades/cart/cart-items.jsx | 133 +- .../upgrades/cart/cart-messages-mixin.jsx | 150 +- .../my-sites/upgrades/cart/cart-plan-ad.jsx | 88 +- .../upgrades/cart/cart-plan-discount-ad.jsx | 164 +- .../upgrades/cart/cart-summary-bar.jsx | 56 +- client/my-sites/upgrades/cart/cart-total.jsx | 88 +- .../my-sites/upgrades/cart/popover-cart.jsx | 257 +- .../my-sites/upgrades/cart/secondary-cart.jsx | 64 +- .../upgrades/cart/test/cart-buttons.js | 95 +- .../business-plan-details.jsx | 87 +- .../checkout-thank-you/chargeback-details.jsx | 29 +- .../custom-domain-purchase-detail.jsx | 88 +- .../domain-mapping-details.jsx | 116 +- .../domain-registration-details.jsx | 116 +- .../failed-purchase-details.jsx | 133 +- .../checkout-thank-you/features-header.jsx | 55 +- .../google-apps-details.jsx | 33 +- .../google-voucher/index.jsx | 468 +- .../google-voucher/terms-and-conditions.jsx | 138 +- .../guided-transfer-details.jsx | 31 +- .../upgrades/checkout-thank-you/header.jsx | 304 +- .../upgrades/checkout-thank-you/index.jsx | 710 +- .../jetpack-plan-details.jsx | 124 +- .../jetpack-thank-you-card.jsx | 708 +- .../personal-plan-details.jsx | 48 +- .../premium-plan-details.jsx | 146 +- .../site-redirect-details.jsx | 66 +- .../upgrades/checkout-thank-you/utils.js | 8 +- .../my-sites/upgrades/checkout/checkout.jsx | 745 +- .../checkout/credit-card-payment-box.jsx | 153 +- .../checkout/credit-card-selector.jsx | 145 +- .../upgrades/checkout/credits-payment-box.jsx | 107 +- .../upgrades/checkout/domain-details-form.jsx | 878 +- .../checkout/free-cart-payment-box.jsx | 115 +- .../checkout/free-trial-confirmation-box.js | 99 +- .../upgrades/checkout/new-card-form.jsx | 111 +- .../my-sites/upgrades/checkout/pay-button.jsx | 278 +- .../upgrades/checkout/payment-box.jsx | 38 +- .../upgrades/checkout/payment-chat-button.jsx | 39 +- .../upgrades/checkout/paypal-payment-box.jsx | 396 +- .../checkout/privacy-protection-dialog.jsx | 170 +- .../checkout/privacy-protection-example.jsx | 176 +- .../upgrades/checkout/privacy-protection.jsx | 170 +- .../secure-payment-form-placeholder.jsx | 51 +- .../upgrades/checkout/secure-payment-form.jsx | 477 +- .../upgrades/checkout/stored-card.jsx | 40 +- .../upgrades/checkout/subscription-text.jsx | 28 +- .../upgrades/checkout/terms-of-service.jsx | 100 +- .../checkout/transaction-steps-mixin.jsx | 255 +- .../components/domain-warnings/index.jsx | 1307 +- .../pending-gapps-tos-notice.jsx | 425 +- .../components/domain-warnings/test/index.js | 504 +- .../components/form/country-select.jsx | 137 +- .../upgrades/components/form/hidden-input.jsx | 93 +- .../upgrades/components/form/index.jsx | 9 +- .../upgrades/components/form/input.jsx | 147 +- .../upgrades/components/form/state-select.jsx | 134 +- client/my-sites/upgrades/controller.jsx | 532 +- .../add-email-addresses-card.jsx | 601 +- .../add-google-apps/domains-select.jsx | 68 +- .../add-google-apps/index.jsx | 100 +- .../designated-agent-notice/index.jsx | 58 +- .../components/domain/main-placeholder.jsx | 38 +- .../components/domain/maintenance-card.jsx | 27 +- .../components/domain/non-owner-card.jsx | 39 +- .../components/domain/primary-flag.jsx | 32 +- .../components/form-footer/index.jsx | 18 +- .../components/header/index.jsx | 48 +- .../icann-verification-card.jsx | 105 +- .../icann-verification/icann-verification.jsx | 106 +- .../contacts-privacy/card.jsx | 191 +- .../contacts-privacy/contact-display.jsx | 59 +- .../contacts-privacy/index.jsx | 121 +- .../upgrades/domain-management/controller.jsx | 629 +- .../domain-management/dns/a-record.jsx | 124 +- .../domain-management/dns/cname-record.jsx | 106 +- .../dns/delete-email-forwards-dialog.jsx | 119 +- .../domain-management/dns/dns-add-new.jsx | 291 +- .../domain-management/dns/dns-details.jsx | 30 +- .../domain-management/dns/dns-list.jsx | 193 +- .../domain-management/dns/dns-record.jsx | 234 +- .../upgrades/domain-management/dns/index.jsx | 180 +- .../domain-management/dns/mx-record.jsx | 173 +- .../domain-management/dns/office-365.jsx | 113 +- .../domain-management/dns/srv-record.jsx | 259 +- .../domain-management/dns/txt-record.jsx | 111 +- .../domain-management/domain-management.jsx | 30 +- .../edit-contact-info/form-card.jsx | 940 +- .../edit-contact-info/index.jsx | 111 +- .../privacy-enabled-card.jsx | 44 +- .../edit/card/header/index.jsx | 54 +- .../card/header/primary-domain-button.jsx | 101 +- .../domain-management/edit/card/property.jsx | 30 +- .../edit/card/subscription-settings.jsx | 32 +- .../upgrades/domain-management/edit/index.jsx | 103 +- .../domain-management/edit/mapped-domain.jsx | 227 +- .../edit/registered-domain.jsx | 442 +- .../domain-management/edit/site-redirect.jsx | 118 +- .../edit/test/mapped-domain.js | 92 +- .../domain-management/edit/wpcom-domain.jsx | 83 +- .../email-forwarding-add-new.jsx | 479 +- .../email-forwarding-details.jsx | 49 +- .../email-forwarding-item.jsx | 198 +- .../email-forwarding-limit.jsx | 35 +- .../email-forwarding-list.jsx | 47 +- .../email-forwarding/index.jsx | 91 +- .../email/add-google-apps-card.jsx | 347 +- .../email/google-apps-user-item.jsx | 63 +- .../email/google-apps-users-card.jsx | 252 +- .../domain-management/email/index.jsx | 246 +- .../domain-management/email/placeholder.jsx | 21 +- .../domain-management/list/constants.js | 6 +- .../list/domain-list-notice.jsx | 125 +- .../domain-management/list/domain-only.jsx | 48 +- .../upgrades/domain-management/list/index.jsx | 729 +- .../list/item-placeholder.jsx | 28 +- .../upgrades/domain-management/list/item.jsx | 275 +- .../domain-management/list/test/index.js | 458 +- .../name-servers/custom-nameservers-form.jsx | 312 +- .../name-servers/custom-nameservers-row.jsx | 94 +- .../domain-management/name-servers/index.jsx | 394 +- .../name-servers/wpcom-nameservers-toggle.jsx | 126 +- .../primary-domain/index.jsx | 324 +- .../privacy-protection/card/add-button.jsx | 60 +- .../privacy-protection/card/content.jsx | 113 +- .../privacy-protection/card/header.jsx | 85 +- .../privacy-protection/index.jsx | 169 +- .../domain-management/site-redirect/index.jsx | 278 +- .../site-redirect/notice.jsx | 56 +- .../domain-management/transfer/index.jsx | 51 +- .../transfer-out/icann-verification.jsx | 108 +- .../transfer/transfer-out/index.jsx | 110 +- .../transfer/transfer-out/locked.jsx | 199 +- .../transfer/transfer-out/shared.js | 142 +- .../transfer-out/transfer-prohibited.jsx | 40 +- .../transfer/transfer-out/unlocked.jsx | 276 +- .../transfer/transfer-to-other-user/index.jsx | 450 +- .../upgrades/domain-search/domain-search.jsx | 312 +- .../domain-search/site-redirect-step.jsx | 292 +- .../upgrades/domain-search/site-redirect.jsx | 108 +- client/my-sites/upgrades/index.js | 496 +- client/my-sites/upgrades/map-domain/index.jsx | 278 +- client/my-sites/upgrades/navigation.jsx | 208 +- client/my-sites/upgrades/paths.js | 146 +- client/my-sites/welcome/welcome.jsx | 97 +- client/notices/index.js | 281 +- client/notices/validation-error-list.jsx | 55 +- client/notifications/index.jsx | 567 +- client/post-editor/controller.js | 460 +- client/post-editor/edit-post-status/index.jsx | 516 +- .../post-editor/editor-action-bar/index.jsx | 125 +- .../editor-action-bar/view-label.jsx | 71 +- client/post-editor/editor-author/index.jsx | 111 +- .../editor-categories-tags/accordion.jsx | 346 +- .../editor-categories-tags/test/accordion.jsx | 347 +- .../post-editor/editor-delete-post/index.jsx | 139 +- .../post-editor/editor-discussion/index.jsx | 221 +- .../editor-discussion/test/index.jsx | 353 +- .../editor-document-head/index.jsx | 96 +- .../post-editor/editor-drawer-well/index.jsx | 117 +- .../editor-drawer/featured-image.jsx | 80 +- client/post-editor/editor-drawer/index.jsx | 617 +- client/post-editor/editor-drawer/label.jsx | 26 +- .../editor-drawer/page-options.jsx | 45 +- .../post-editor/editor-drawer/taxonomies.jsx | 140 +- .../editor-featured-image/index.jsx | 216 +- .../preview-container.jsx | 123 +- .../editor-featured-image/preview.jsx | 211 +- client/post-editor/editor-fieldset/index.jsx | 47 +- client/post-editor/editor-forbidden/index.jsx | 63 +- .../editor-ground-control/index.jsx | 787 +- .../editor-ground-control/test/index.jsx | 265 +- .../editor-html-toolbar/add-image-dialog.jsx | 192 +- .../editor-html-toolbar/add-link-dialog.jsx | 361 +- .../post-editor/editor-html-toolbar/index.jsx | 1171 +- client/post-editor/editor-location/index.jsx | 271 +- .../editor-location/search-result.jsx | 40 +- client/post-editor/editor-location/search.jsx | 206 +- .../editor-media-advanced/index.jsx | 94 +- .../post-editor/editor-media-modal/index.jsx | 146 +- .../editor-more-options/copy-post.jsx | 221 +- .../post-editor/editor-more-options/slug.jsx | 69 +- client/post-editor/editor-notice/index.jsx | 451 +- .../post-editor/editor-notice/test/index.jsx | 200 +- .../post-editor/editor-page-order/index.jsx | 107 +- .../post-editor/editor-page-parent/index.jsx | 116 +- client/post-editor/editor-page-slug/index.jsx | 20 +- .../editor-page-templates/index.jsx | 165 +- client/post-editor/editor-permalink/index.jsx | 294 +- .../editor-post-formats/accordion.jsx | 118 +- .../post-editor/editor-post-formats/index.jsx | 218 +- .../editor-post-type-unsupported/index.jsx | 160 +- client/post-editor/editor-post-type/index.jsx | 123 +- client/post-editor/editor-preview/index.jsx | 186 +- .../editor-publish-button/index.jsx | 241 +- .../editor-publish-button/test/index.jsx | 673 +- client/post-editor/editor-revisions/index.jsx | 89 +- .../editor-seo-accordion/index.jsx | 156 +- .../post-editor/editor-sharing/accordion.jsx | 254 +- client/post-editor/editor-sharing/index.jsx | 18 +- .../editor-sharing/publicize-connection.jsx | 150 +- .../editor-sharing/publicize-message.jsx | 179 +- .../editor-sharing/publicize-options.jsx | 441 +- .../editor-sharing/publicize-services.jsx | 53 +- .../editor-sharing/sharing-like-options.jsx | 224 +- .../test/publicize-connection.jsx | 184 +- client/post-editor/editor-sidebar/header.jsx | 36 +- client/post-editor/editor-sidebar/index.jsx | 95 +- client/post-editor/editor-slug/index.jsx | 247 +- .../post-editor/editor-status-label/index.jsx | 316 +- .../editor-status-label/placeholder.jsx | 83 +- client/post-editor/editor-sticky/index.jsx | 138 +- .../editor-term-selector/add-term.jsx | 108 +- .../editor-term-selector/index.jsx | 148 +- .../post-editor/editor-theme-help/index.jsx | 68 +- client/post-editor/editor-title/index.jsx | 190 +- .../post-editor/editor-visibility/index.jsx | 736 +- .../post-editor/editor-word-count/index.jsx | 102 +- client/post-editor/index.js | 48 +- client/post-editor/invalid-url-dialog.jsx | 130 +- .../media-modal/back-to-library.jsx | 22 +- .../media-modal/detail/detail-fields.jsx | 281 +- .../media-modal/detail/detail-file-info.jsx | 212 +- .../media-modal/detail/detail-item.jsx | 483 +- .../detail/detail-preview-audio.jsx | 27 +- .../detail/detail-preview-document.jsx | 28 +- .../detail/detail-preview-image.jsx | 154 +- .../detail/detail-preview-video.jsx | 37 +- .../detail/detail-preview-videopress.jsx | 163 +- .../post-editor/media-modal/detail/index.jsx | 138 +- client/post-editor/media-modal/fieldset.jsx | 37 +- .../post-editor/media-modal/gallery-help.jsx | 265 +- .../media-modal/gallery/caption.jsx | 97 +- .../media-modal/gallery/drop-zone.jsx | 77 +- .../media-modal/gallery/edit-item.jsx | 85 +- .../post-editor/media-modal/gallery/edit.jsx | 103 +- .../media-modal/gallery/fields.jsx | 299 +- .../post-editor/media-modal/gallery/index.jsx | 272 +- .../gallery/preview-individual.jsx | 72 +- .../media-modal/gallery/preview-shortcode.jsx | 91 +- .../media-modal/gallery/preview.jsx | 160 +- .../media-modal/gallery/remove-button.jsx | 69 +- client/post-editor/media-modal/index.jsx | 890 +- client/post-editor/media-modal/markup.js | 316 +- .../post-editor/media-modal/preload-image.js | 12 +- .../media-modal/secondary-actions.jsx | 171 +- client/post-editor/media-modal/test/index.jsx | 296 +- client/post-editor/media-modal/test/markup.js | 595 +- .../media-modal/test/preload-image.js | 54 +- client/post-editor/post-editor.jsx | 1666 +- client/post-editor/restore-post-dialog.jsx | 165 +- client/post-editor/term-token-field/index.jsx | 176 +- client/post-editor/test/post-editor.jsx | 394 +- client/post-editor/verify-email-dialog.jsx | 204 +- client/reader/controller-helper.js | 91 +- client/reader/controller.js | 544 +- client/reader/discover/controller.js | 76 +- client/reader/discover/follow-button.jsx | 74 +- client/reader/discover/helper.js | 105 +- client/reader/discover/index.js | 17 +- client/reader/discover/post-attribution.jsx | 128 +- client/reader/discover/site-attribution.jsx | 101 +- client/reader/discover/stats.js | 44 +- client/reader/discover/test/fixtures.js | 114 +- client/reader/discover/test/helper.js | 275 +- client/reader/embed-helper.jsx | 183 +- client/reader/feed-error/index.jsx | 93 +- client/reader/feed-stream/empty.jsx | 84 +- client/reader/feed-stream/index.jsx | 312 +- .../reader/follow-button/follow-sources.jsx | 12 +- client/reader/follow-button/index.jsx | 90 +- client/reader/following-edit/empty.jsx | 79 +- .../reader/following-edit/export-button.jsx | 97 +- .../reader/following-edit/import-button.jsx | 112 +- client/reader/following-edit/index.jsx | 1173 +- client/reader/following-edit/list-item.jsx | 272 +- client/reader/following-edit/navigation.jsx | 49 +- .../following-edit/notification-settings.jsx | 442 +- client/reader/following-edit/placeholder.jsx | 39 +- .../reader/following-edit/sort-controls.jsx | 67 +- .../following-edit/subscribe-form-result.jsx | 40 +- .../reader/following-edit/subscribe-form.jsx | 309 +- client/reader/following-manage/index.jsx | 17 +- client/reader/following/controller.js | 80 +- client/reader/following/index.js | 20 +- client/reader/following/main.jsx | 71 +- client/reader/full-post/controller.js | 126 +- client/reader/full-post/index.js | 28 +- client/reader/header-back/index.jsx | 8 +- client/reader/index.js | 97 +- client/reader/lib/content-width/index.js | 28 +- .../reader/lib/feed-display-helper/index.js | 96 +- client/reader/like-button/index.jsx | 56 +- client/reader/like-helper.jsx | 22 +- client/reader/liked-stream/controller.js | 57 +- client/reader/liked-stream/empty.jsx | 87 +- client/reader/liked-stream/index.js | 17 +- client/reader/liked-stream/main.jsx | 36 +- client/reader/list-gap/index.jsx | 83 +- client/reader/list-item/actions.jsx | 12 +- client/reader/list-item/description.jsx | 14 +- client/reader/list-item/icon.jsx | 24 +- client/reader/list-item/index.jsx | 23 +- client/reader/list-item/title.jsx | 22 +- client/reader/list-stream/empty.jsx | 87 +- client/reader/list-stream/header.jsx | 103 +- client/reader/list-stream/index.jsx | 160 +- client/reader/list-stream/missing.jsx | 107 +- client/reader/list/controller.js | 76 +- client/reader/list/index.js | 7 +- client/reader/post-excerpt-link/index.jsx | 124 +- client/reader/post-time/index.jsx | 56 +- client/reader/reading-time/index.jsx | 65 +- client/reader/recommendations/controller.js | 167 +- .../reader/recommendations/for-you/index.jsx | 256 +- .../recommendations/global-tags/index.jsx | 20 +- client/reader/recommendations/index.js | 59 +- .../recommendations/navigation/index.jsx | 52 +- client/reader/recommendations/posts/empty.jsx | 89 +- client/reader/recommendations/posts/index.jsx | 40 +- client/reader/recommendations/sites/index.jsx | 20 +- client/reader/route/index.js | 62 +- client/reader/route/test/index.js | 52 +- client/reader/search-stream/empty.jsx | 119 +- client/reader/search-stream/index.jsx | 547 +- .../search-stream/suggestion-provider.jsx | 91 +- client/reader/search-stream/suggestion.jsx | 33 +- client/reader/search-stream/suggestions.js | 229 +- client/reader/search/controller.js | 129 +- client/reader/search/index.js | 22 +- client/reader/share/helper.jsx | 8 +- client/reader/share/index.jsx | 405 +- client/reader/sidebar/expandable-add-form.jsx | 120 +- client/reader/sidebar/expandable-heading.jsx | 20 +- client/reader/sidebar/expandable.jsx | 72 +- client/reader/sidebar/helper.js | 57 +- client/reader/sidebar/index.jsx | 404 +- .../sidebar/reader-sidebar-lists/index.jsx | 91 +- .../reader-sidebar-lists/list-item.jsx | 89 +- .../sidebar/reader-sidebar-lists/list.jsx | 80 +- .../sidebar/reader-sidebar-tags/index.jsx | 138 +- .../sidebar/reader-sidebar-tags/list-item.jsx | 100 +- .../sidebar/reader-sidebar-tags/list.jsx | 80 +- .../sidebar/reader-sidebar-teams/index.jsx | 26 +- .../reader-sidebar-teams/list-item.jsx | 45 +- client/reader/sidebar/test/index.jsx | 197 +- client/reader/site-and-author-icon/index.jsx | 101 +- client/reader/site-stream/empty.jsx | 84 +- client/reader/site-stream/featured.jsx | 257 +- client/reader/site-stream/index.jsx | 292 +- client/reader/stats.js | 341 +- client/reader/stream/empty.jsx | 67 +- client/reader/stream/index.jsx | 999 +- client/reader/stream/post-lifecycle.jsx | 155 +- client/reader/stream/post-placeholder.jsx | 72 +- client/reader/stream/post-unavailable.jsx | 89 +- client/reader/stream/post.jsx | 334 +- client/reader/stream/recommended-posts.jsx | 170 +- client/reader/stream/test/utils.js | 521 +- client/reader/stream/utils.js | 129 +- client/reader/stream/x-post.jsx | 306 +- client/reader/tag-stream/controller.js | 80 +- client/reader/tag-stream/empty.jsx | 107 +- client/reader/tag-stream/header.jsx | 185 +- client/reader/tag-stream/index.js | 37 +- client/reader/tag-stream/main.jsx | 238 +- client/reader/team/main.jsx | 9 +- client/reader/test/utils.js | 68 +- client/reader/update-notice/index.jsx | 85 +- client/reader/utils.js | 224 +- client/reader/xpost-helper.js | 66 +- client/sections-preload.js | 6 +- client/sections.js | 58 +- client/signup/config/flows.js | 612 +- client/signup/config/step-components.js | 41 +- client/signup/config/steps.js | 297 +- client/signup/config/test/index.js | 39 +- client/signup/config/test/lib/user/index.js | 10 +- client/signup/controller.js | 144 +- .../signup/flow-progress-indicator/index.jsx | 44 +- client/signup/index.node.js | 57 +- client/signup/index.web.js | 148 +- .../signup/jetpack-connect/authorize-form.jsx | 1455 +- client/signup/jetpack-connect/controller.js | 469 +- .../example-components/jetpack-activate.jsx | 121 +- .../example-components/jetpack-connect.jsx | 120 +- .../example-components/jetpack-install.jsx | 76 +- client/signup/jetpack-connect/help-button.jsx | 27 +- client/signup/jetpack-connect/index.jsx | 889 +- .../signup/jetpack-connect/install-step.jsx | 218 +- .../jetpack-connect-notices.jsx | 257 +- .../signup/jetpack-connect/main-wrapper.jsx | 22 +- client/signup/jetpack-connect/plans-grid.jsx | 91 +- .../signup/jetpack-connect/plans-landing.jsx | 111 +- client/signup/jetpack-connect/plans.jsx | 548 +- .../signup/jetpack-connect/site-url-input.jsx | 186 +- client/signup/jetpack-connect/sso.jsx | 904 +- .../jetpack-connect/test/main-wrapper.jsx | 72 +- client/signup/locale-suggestions/index.jsx | 203 +- client/signup/main.jsx | 899 +- client/signup/navigation-link/index.jsx | 200 +- client/signup/previous-step-button/index.jsx | 94 +- client/signup/processing-screen/index.jsx | 291 +- client/signup/step-header/index.jsx | 39 +- client/signup/step-wrapper/index.jsx | 154 +- .../design-type-with-store/blog-image.jsx | 10 +- .../design-type-with-store/domain-image.jsx | 8 +- .../design-type-with-store/grid-image.jsx | 18 +- .../steps/design-type-with-store/index.jsx | 424 +- .../design-type-with-store/page-image.jsx | 20 +- .../pressable-store/hero-image.jsx | 114 +- .../pressable-store/index.jsx | 264 +- .../design-type-with-store/store-image.jsx | 22 +- client/signup/steps/design-type/index.jsx | 148 +- client/signup/steps/domains/index.jsx | 518 +- .../signup/steps/get-dot-blog-plans/index.jsx | 28 +- .../signup/steps/plans-without-free/index.jsx | 2 +- client/signup/steps/plans/index.jsx | 235 +- client/signup/steps/site-or-domain/index.jsx | 224 +- client/signup/steps/site-title/index.jsx | 113 +- client/signup/steps/site/index.jsx | 506 +- client/signup/steps/survey/index.jsx | 334 +- client/signup/steps/survey/verticals.js | 46 +- client/signup/steps/test-step/index.jsx | 48 +- client/signup/steps/theme-selection/index.jsx | 146 +- .../theme-selection/signup-themes-list.jsx | 86 +- client/signup/steps/user/index.jsx | 341 +- client/signup/steps/user/test/index.js | 216 +- client/signup/submit-step-button/index.jsx | 28 +- client/signup/test/fixtures/flows.js | 32 +- client/signup/test/flows.js | 268 +- client/signup/test/lib/user/index.js | 18 +- client/signup/test/signup/config/steps.js | 4 +- client/signup/test/utils.js | 429 +- client/signup/utils.js | 169 +- client/signup/validation-fieldset/index.jsx | 45 +- client/signup/wpcom-login-form/index.jsx | 103 +- client/state/account-recovery/reducer.js | 26 +- .../state/account-recovery/reset/actions.js | 135 +- .../state/account-recovery/reset/reducer.js | 67 +- .../account-recovery/reset/test/actions.js | 114 +- .../account-recovery/reset/test/reducer.js | 298 +- client/state/account-recovery/selectors.js | 2 +- .../account-recovery/settings/actions.js | 437 +- .../account-recovery/settings/reducer.js | 259 +- .../account-recovery/settings/selectors.js | 76 +- .../account-recovery/settings/test/actions.js | 959 +- .../account-recovery/settings/test/reducer.js | 402 +- .../settings/test/selectors.js | 714 +- .../settings/test/test-data.js | 26 +- .../account-recovery/settings/test/utils.js | 94 +- client/state/account-recovery/test/reducer.js | 68 +- .../state/account-recovery/test/selectors.js | 24 +- client/state/analytics/actions.js | 128 +- client/state/analytics/middleware.js | 55 +- client/state/analytics/test/actions.js | 121 +- .../analytics/test/helpers/analytics-mock.js | 18 +- client/state/analytics/test/middleware.js | 90 +- client/state/application/actions.js | 64 +- client/state/application/reducer.js | 19 +- client/state/application/selectors.js | 10 +- client/state/application/test/actions.js | 102 +- client/state/application/test/reducer.js | 77 +- client/state/audio/middleware.js | 61 +- client/state/audio/test/middleware.js | 138 +- client/state/automated-transfer/actions.js | 43 +- client/state/automated-transfer/constants.js | 36 +- .../automated-transfer/eligibility/reducer.js | 31 +- .../automated-transfer/eligibility/schema.js | 38 +- client/state/automated-transfer/middleware.js | 46 +- client/state/automated-transfer/reducer.js | 47 +- client/state/automated-transfer/schema.js | 20 +- client/state/automated-transfer/selectors.js | 31 +- .../state/automated-transfer/test/reducer.js | 32 +- client/state/billing-transactions/actions.js | 104 +- client/state/billing-transactions/reducer.js | 63 +- client/state/billing-transactions/schema.js | 102 +- .../billing-transactions/test/actions.js | 294 +- .../billing-transactions/test/reducer.js | 434 +- .../state/billing-transactions/test/util.js | 30 +- client/state/billing-transactions/util.js | 4 +- client/state/comments/actions.js | 462 +- client/state/comments/constants.js | 4 +- client/state/comments/reducer.js | 245 +- client/state/comments/selectors.js | 77 +- client/state/comments/test/actions.js | 688 +- client/state/comments/test/reducer.js | 550 +- client/state/comments/test/selectors.js | 193 +- client/state/comments/test/utils.js | 218 +- client/state/comments/utils.js | 101 +- .../state/components-usage-stats/actions.js | 41 +- .../state/components-usage-stats/reducer.js | 42 +- .../components-usage-stats/test/actions.js | 56 +- .../components-usage-stats/test/reducer.js | 73 +- client/state/console-dispatch/index.js | 131 +- client/state/country-states/actions.js | 67 +- client/state/country-states/reducer.js | 48 +- client/state/country-states/schema.js | 41 +- client/state/country-states/selectors.js | 8 +- client/state/country-states/test/actions.js | 157 +- client/state/country-states/test/reducer.js | 231 +- client/state/country-states/test/selectors.js | 105 +- client/state/current-user/actions.js | 20 +- client/state/current-user/constants.js | 2 +- .../current-user/gravatar-status/actions.js | 78 +- .../current-user/gravatar-status/reducer.js | 43 +- .../current-user/gravatar-status/selectors.js | 10 +- .../gravatar-status/test/actions.js | 166 +- .../gravatar-status/test/reducer.js | 144 +- .../gravatar-status/test/selectors.js | 170 +- client/state/current-user/reducer.js | 126 +- client/state/current-user/schema.js | 60 +- client/state/current-user/selectors.js | 84 +- client/state/current-user/test/actions.js | 22 +- client/state/current-user/test/reducer.js | 708 +- client/state/current-user/test/selectors.js | 508 +- client/state/data-layer/test/utils.js | 109 +- .../data-layer/test/wpcom-api-middleware.js | 253 +- .../data-layer/third-party/directly/index.js | 63 +- .../third-party/directly/test/index.js | 247 +- client/state/data-layer/third-party/index.js | 4 +- client/state/data-layer/utils.js | 28 +- .../state/data-layer/wpcom-api-middleware.js | 56 +- client/state/data-layer/wpcom-http/actions.js | 49 +- client/state/data-layer/wpcom-http/index.js | 87 +- .../state/data-layer/wpcom-http/test/utils.js | 232 +- client/state/data-layer/wpcom-http/utils.js | 37 +- .../wpcom/account-recovery/index.js | 7 +- .../wpcom/account-recovery/lookup/index.js | 55 +- .../account-recovery/lookup/test/index.js | 140 +- .../account-recovery/request-reset/index.js | 24 +- .../request-reset/test/index.js | 96 +- .../wpcom/account-recovery/reset/index.js | 33 +- .../account-recovery/reset/test/index.js | 91 +- .../wpcom/account-recovery/validate/index.js | 24 +- .../account-recovery/validate/test/index.js | 99 +- client/state/data-layer/wpcom/index.js | 8 +- client/state/data-layer/wpcom/plans/index.js | 44 +- .../data-layer/wpcom/plans/test/index.js | 114 +- client/state/data-layer/wpcom/read/index.js | 5 +- .../state/data-layer/wpcom/read/tags/index.js | 93 +- .../wpcom/read/tags/mine/delete/index.js | 62 +- .../wpcom/read/tags/mine/delete/test/index.js | 223 +- .../wpcom/read/tags/mine/new/index.js | 80 +- .../wpcom/read/tags/mine/new/test/index.js | 224 +- .../data-layer/wpcom/read/tags/test/index.js | 278 +- .../data-layer/wpcom/read/tags/test/utils.js | 144 +- .../state/data-layer/wpcom/read/tags/utils.js | 36 +- .../data-layer/wpcom/read/teams/index.js | 38 +- .../data-layer/wpcom/read/teams/test/index.js | 87 +- .../automated-transfer/eligibility/index.js | 78 +- .../wpcom/sites/automated-transfer/index.js | 4 +- client/state/data-layer/wpcom/sites/index.js | 5 +- .../data-layer/wpcom/sites/media/index.js | 78 +- .../wpcom/sites/media/test/index.js | 104 +- .../state/data-layer/wpcom/timezones/index.js | 51 +- .../data-layer/wpcom/timezones/test/index.js | 164 +- client/state/document-head/actions.js | 48 +- client/state/document-head/reducer.js | 82 +- client/state/document-head/selectors.js | 66 +- client/state/document-head/test/actions.js | 92 +- client/state/document-head/test/reducer.js | 182 +- client/state/document-head/test/selectors.js | 493 +- client/state/domains/reducer.js | 6 +- client/state/domains/suggestions/actions.js | 64 +- client/state/domains/suggestions/reducer.js | 141 +- client/state/domains/suggestions/schema.js | 36 +- client/state/domains/suggestions/selectors.js | 36 +- .../state/domains/suggestions/test/actions.js | 181 +- .../state/domains/suggestions/test/reducer.js | 936 +- .../domains/suggestions/test/selectors.js | 244 +- .../state/domains/suggestions/test/utils.js | 152 +- client/state/domains/suggestions/utils.js | 36 +- client/state/domains/test/reducer.js | 12 +- client/state/followers/actions.js | 75 +- client/state/followers/reducer.js | 169 +- client/state/followers/selectors.js | 18 +- client/state/followers/test/reducer.js | 279 +- client/state/followers/test/selectors.js | 79 +- client/state/followers/test/utils.js | 61 +- client/state/followers/utils.js | 10 +- client/state/geo/actions.js | 45 +- client/state/geo/reducer.js | 36 +- client/state/geo/schema.js | 18 +- client/state/geo/selectors.js | 12 +- client/state/geo/test/actions.js | 181 +- client/state/geo/test/reducer.js | 213 +- client/state/geo/test/selectors.js | 122 +- client/state/google-apps-users/actions.js | 84 +- client/state/google-apps-users/reducer.js | 60 +- client/state/google-apps-users/selectors.js | 22 +- .../state/google-apps-users/test/actions.js | 255 +- .../state/google-apps-users/test/reducer.js | 91 +- .../state/google-apps-users/test/selectors.js | 74 +- client/state/happiness-engineers/actions.js | 54 +- client/state/happiness-engineers/reducer.js | 40 +- client/state/happiness-engineers/schema.js | 10 +- client/state/happiness-engineers/selectors.js | 12 +- .../state/happiness-engineers/test/actions.js | 142 +- .../state/happiness-engineers/test/reducer.js | 206 +- .../happiness-engineers/test/selectors.js | 66 +- client/state/happychat/actions.js | 226 +- client/state/happychat/middleware.js | 52 +- client/state/happychat/reducer.js | 215 +- client/state/happychat/selectors.js | 31 +- client/state/happychat/test/middleware.js | 57 +- client/state/help/courses/actions.js | 14 +- client/state/help/courses/reducer.js | 16 +- client/state/help/courses/selectors.js | 4 +- client/state/help/courses/test/actions.js | 46 +- client/state/help/courses/test/reducer.js | 65 +- client/state/help/courses/test/selectors.js | 66 +- client/state/help/directly/actions.js | 18 +- client/state/help/directly/reducer.js | 29 +- client/state/help/directly/test/actions.js | 83 +- client/state/help/directly/test/reducer.js | 66 +- client/state/help/reducer.js | 10 +- client/state/help/ticket/actions.js | 53 +- client/state/help/ticket/reducer.js | 55 +- client/state/help/ticket/selectors.js | 16 +- client/state/help/ticket/test/actions.js | 180 +- client/state/help/ticket/test/reducer.js | 149 +- client/state/help/ticket/test/selectors.js | 132 +- client/state/help/ticket/test/test-data.js | 6 +- client/state/imports/constants.js | 30 +- client/state/index.js | 136 +- client/state/initial-state.js | 127 +- client/state/jetpack-connect/actions.js | 917 +- client/state/jetpack-connect/reducer.js | 571 +- client/state/jetpack-connect/schema.js | 124 +- client/state/jetpack-connect/selectors.js | 202 +- client/state/jetpack-connect/test/actions.js | 1156 +- client/state/jetpack-connect/test/reducer.js | 1629 +- .../state/jetpack-connect/test/selectors.js | 1311 +- client/state/jetpack-connect/test/utils.js | 62 +- client/state/jetpack-connect/utils.js | 12 +- client/state/jetpack-sync/actions.js | 114 +- client/state/jetpack-sync/reducer.js | 184 +- client/state/jetpack-sync/selectors.js | 153 +- client/state/jetpack-sync/test/actions.js | 370 +- client/state/jetpack-sync/test/reducer.js | 718 +- client/state/jetpack-sync/test/selectors.js | 624 +- client/state/jetpack-sync/utils.js | 30 +- client/state/jetpack/connection/actions.js | 61 +- client/state/jetpack/connection/reducer.js | 49 +- .../state/jetpack/connection/test/actions.js | 146 +- .../state/jetpack/connection/test/fixture.js | 44 +- .../state/jetpack/connection/test/reducer.js | 248 +- client/state/jetpack/jumpstart/actions.js | 159 +- client/state/jetpack/jumpstart/reducer.js | 81 +- .../state/jetpack/jumpstart/test/actions.js | 432 +- .../state/jetpack/jumpstart/test/fixture.js | 34 +- .../state/jetpack/jumpstart/test/reducer.js | 546 +- client/state/jetpack/modules/actions.js | 198 +- client/state/jetpack/modules/reducer.js | 172 +- client/state/jetpack/modules/test/actions.js | 481 +- client/state/jetpack/modules/test/fixture.js | 132 +- client/state/jetpack/modules/test/reducer.js | 544 +- client/state/jetpack/reducer.js | 12 +- client/state/jetpack/settings/actions.js | 172 +- client/state/jetpack/settings/reducer.js | 207 +- client/state/jetpack/settings/test/actions.js | 454 +- client/state/jetpack/settings/test/fixture.js | 60 +- client/state/jetpack/settings/test/reducer.js | 929 +- client/state/jetpack/settings/test/utils.js | 761 +- client/state/jetpack/settings/utils.js | 187 +- client/state/media/actions.js | 144 +- client/state/media/reducer.js | 185 +- client/state/media/test/actions.js | 265 +- client/state/media/test/reducer.js | 551 +- .../state/notices/account-recovery/index.js | 221 +- client/state/notices/actions.js | 51 +- .../notices/jetpack-modules/constants.js | 20 +- client/state/notices/jetpack-modules/index.js | 74 +- client/state/notices/middleware.js | 459 +- client/state/notices/reducer.js | 83 +- client/state/notices/selectors.js | 4 +- client/state/notices/test/actions.js | 90 +- client/state/notices/test/middleware.js | 480 +- client/state/notices/test/reducer.js | 174 +- client/state/notices/test/selectors.js | 42 +- client/state/notices/utils.js | 8 +- client/state/page-templates/actions.js | 64 +- client/state/page-templates/reducer.js | 55 +- client/state/page-templates/schema.js | 30 +- client/state/page-templates/selectors.js | 8 +- client/state/page-templates/test/actions.js | 145 +- client/state/page-templates/test/reducer.js | 409 +- client/state/page-templates/test/selectors.js | 123 +- client/state/pages/selectors.js | 14 +- client/state/pages/test/selectors.js | 243 +- client/state/plans/actions.js | 32 +- client/state/plans/reducer.js | 96 +- client/state/plans/schema.js | 90 +- client/state/plans/selectors.js | 30 +- client/state/plans/test/actions.js | 60 +- client/state/plans/test/fixture.js | 664 +- client/state/plans/test/reducer.js | 278 +- client/state/plans/test/selectors.js | 306 +- client/state/plugins/installed/actions.js | 598 +- client/state/plugins/installed/reducer.js | 188 +- client/state/plugins/installed/schema.js | 50 +- client/state/plugins/installed/selectors.js | 201 +- .../state/plugins/installed/status/reducer.js | 236 +- .../state/plugins/installed/test/actions.js | 1152 +- .../installed/test/fixtures/plugins.js | 118 +- .../state/plugins/installed/test/reducer.js | 392 +- .../state/plugins/installed/test/selectors.js | 571 +- client/state/plugins/premium/actions.js | 533 +- client/state/plugins/premium/reducer.js | 240 +- client/state/plugins/premium/schema.js | 36 +- client/state/plugins/premium/selectors.js | 134 +- client/state/plugins/premium/test/examples.js | 280 +- client/state/plugins/premium/test/reducer.js | 329 +- .../state/plugins/premium/test/selectors.js | 274 +- client/state/plugins/reducer.js | 10 +- client/state/plugins/wporg/actions.js | 55 +- client/state/plugins/wporg/reducer.js | 87 +- client/state/plugins/wporg/selectors.js | 40 +- client/state/plugins/wporg/test/actions.js | 131 +- .../plugins/wporg/test/lib/mock-wporg.js | 50 +- client/state/plugins/wporg/test/reducer.js | 179 +- client/state/plugins/wporg/test/selectors.js | 116 +- client/state/post-formats/actions.js | 61 +- client/state/post-formats/reducer.js | 43 +- client/state/post-formats/schema.js | 34 +- client/state/post-formats/selectors.js | 8 +- client/state/post-formats/test/actions.js | 132 +- client/state/post-formats/test/reducer.js | 459 +- client/state/post-formats/test/selectors.js | 136 +- client/state/post-types/actions.js | 65 +- client/state/post-types/reducer.js | 74 +- client/state/post-types/schema.js | 44 +- client/state/post-types/selectors.js | 82 +- client/state/post-types/taxonomies/actions.js | 80 +- client/state/post-types/taxonomies/reducer.js | 80 +- client/state/post-types/taxonomies/schema.js | 64 +- .../state/post-types/taxonomies/selectors.js | 28 +- .../post-types/taxonomies/test/actions.js | 163 +- .../post-types/taxonomies/test/reducer.js | 562 +- .../post-types/taxonomies/test/selectors.js | 448 +- client/state/post-types/test/actions.js | 151 +- client/state/post-types/test/reducer.js | 431 +- client/state/post-types/test/selectors.js | 532 +- client/state/posts/actions.js | 394 +- client/state/posts/constants.js | 42 +- client/state/posts/counts/actions.js | 77 +- client/state/posts/counts/reducer.js | 299 +- client/state/posts/counts/schema.js | 50 +- client/state/posts/counts/selectors.js | 89 +- client/state/posts/counts/test/actions.js | 171 +- client/state/posts/counts/test/reducer.js | 988 +- client/state/posts/counts/test/selectors.js | 715 +- client/state/posts/likes/actions.js | 73 +- client/state/posts/likes/reducer.js | 84 +- client/state/posts/likes/schema.js | 62 +- client/state/posts/likes/test/actions.js | 136 +- client/state/posts/likes/test/reducer.js | 724 +- client/state/posts/reducer.js | 526 +- client/state/posts/schema.js | 116 +- client/state/posts/selectors.js | 465 +- client/state/posts/test/actions.js | 1185 +- client/state/posts/test/reducer.js | 2423 +-- client/state/posts/test/selectors.js | 3949 ++--- client/state/posts/test/utils.js | 897 +- client/state/posts/utils.js | 277 +- client/state/preferences/actions.js | 123 +- client/state/preferences/constants.js | 16 +- client/state/preferences/reducer.js | 75 +- client/state/preferences/schema.js | 108 +- client/state/preferences/selectors.js | 27 +- client/state/preferences/test/actions.js | 306 +- client/state/preferences/test/reducer.js | 316 +- client/state/preferences/test/selectors.js | 152 +- client/state/preview/actions.js | 103 +- client/state/preview/reducer.js | 104 +- .../state/preview/save-functions/actions.js | 18 +- client/state/preview/save-functions/index.js | 10 +- client/state/preview/schema.js | 61 +- client/state/preview/selectors.js | 16 +- client/state/products-list/actions.js | 37 +- client/state/products-list/reducer.js | 34 +- client/state/products-list/schema.js | 53 +- client/state/products-list/selectors.js | 16 +- client/state/products-list/test/actions.js | 126 +- client/state/products-list/test/reducer.js | 269 +- client/state/products-list/test/selectors.js | 65 +- client/state/purchases/actions.js | 227 +- client/state/purchases/reducer.js | 227 +- client/state/purchases/selectors.js | 54 +- client/state/purchases/test/actions.js | 277 +- client/state/purchases/test/reducer.js | 445 +- client/state/purchases/test/selectors.js | 516 +- client/state/push-notifications/actions.js | 555 +- client/state/push-notifications/reducer.js | 293 +- client/state/push-notifications/schema.js | 53 +- client/state/push-notifications/selectors.js | 68 +- .../state/push-notifications/test/actions.js | 120 +- .../state/push-notifications/test/reducer.js | 308 +- .../push-notifications/test/selectors.js | 238 +- client/state/push-notifications/utils.js | 41 +- client/state/reader/feeds/actions.js | 80 +- client/state/reader/feeds/reducer.js | 137 +- client/state/reader/feeds/schema.js | 38 +- client/state/reader/feeds/selectors.js | 9 +- client/state/reader/feeds/test/actions.js | 146 +- client/state/reader/feeds/test/reducer.js | 306 +- client/state/reader/feeds/test/selectors.js | 124 +- client/state/reader/follows/actions.js | 108 +- client/state/reader/follows/reducer.js | 77 +- client/state/reader/follows/test/actions.js | 228 +- client/state/reader/follows/test/reducer.js | 118 +- client/state/reader/follows/utils.js | 12 +- client/state/reader/lists/actions.js | 388 +- client/state/reader/lists/reducer.js | 328 +- client/state/reader/lists/schema.js | 42 +- client/state/reader/lists/selectors.js | 85 +- client/state/reader/lists/test/actions.js | 386 +- client/state/reader/lists/test/reducer.js | 483 +- client/state/reader/lists/test/selectors.js | 556 +- client/state/reader/posts/actions.js | 222 +- client/state/reader/posts/display-types.js | 24 +- .../state/reader/posts/normalization-rules.js | 207 +- client/state/reader/posts/reducer.js | 40 +- client/state/reader/posts/schema.js | 2 +- client/state/reader/posts/selectors.js | 34 +- client/state/reader/posts/test/actions.js | 376 +- .../reader/posts/test/normalization-rules.js | 273 +- client/state/reader/posts/test/reducer.js | 20 +- client/state/reader/posts/test/selectors.js | 164 +- client/state/reader/reducer.js | 26 +- client/state/reader/related-posts/actions.js | 146 +- client/state/reader/related-posts/reducer.js | 61 +- .../state/reader/related-posts/selectors.js | 10 +- .../reader/related-posts/test/actions.js | 249 +- .../reader/related-posts/test/reducer.js | 171 +- .../reader/related-posts/test/selectors.js | 161 +- client/state/reader/related-posts/utils.js | 4 +- client/state/reader/site-blocks/actions.js | 142 +- client/state/reader/site-blocks/reducer.js | 41 +- .../state/reader/site-blocks/test/actions.js | 382 +- .../state/reader/site-blocks/test/reducer.js | 172 +- client/state/reader/sites/actions.js | 80 +- client/state/reader/sites/reducer.js | 163 +- client/state/reader/sites/schema.js | 22 +- client/state/reader/sites/selectors.js | 9 +- client/state/reader/sites/test/actions.js | 146 +- client/state/reader/sites/test/reducer.js | 423 +- client/state/reader/sites/test/selectors.js | 124 +- client/state/reader/start/actions.js | 56 +- client/state/reader/start/reducer.js | 60 +- client/state/reader/start/selectors.js | 20 +- client/state/reader/start/test/actions.js | 74 +- client/state/reader/start/test/selectors.js | 157 +- client/state/reader/tags/images/actions.js | 84 +- client/state/reader/tags/images/reducer.js | 82 +- client/state/reader/tags/images/selectors.js | 17 +- .../state/reader/tags/images/test/actions.js | 106 +- .../state/reader/tags/images/test/reducer.js | 208 +- .../reader/tags/images/test/selectors.js | 120 +- client/state/reader/tags/items/actions.js | 78 +- client/state/reader/tags/items/reducer.js | 51 +- .../state/reader/tags/items/test/actions.js | 68 +- .../state/reader/tags/items/test/reducer.js | 115 +- client/state/reader/tags/reducer.js | 8 +- client/state/reader/teams/actions.js | 11 +- client/state/reader/teams/reducer.js | 31 +- client/state/reader/teams/schema.js | 17 +- client/state/reader/teams/test/reducer.js | 156 +- client/state/reader/thumbnails/actions.js | 125 +- client/state/reader/thumbnails/reducer.js | 74 +- client/state/reader/thumbnails/selectors.js | 8 +- .../state/reader/thumbnails/test/actions.js | 232 +- .../state/reader/thumbnails/test/reducer.js | 183 +- .../thumbnails/test/sample-vimeo-response.js | 52 +- .../state/reader/thumbnails/test/selectors.js | 93 +- client/state/receipts/actions.js | 67 +- client/state/receipts/assembler.js | 56 +- client/state/receipts/reducer.js | 80 +- client/state/receipts/selectors.js | 4 +- client/state/receipts/test/reducer.js | 198 +- .../selectors/are-site-permalinks-editable.js | 12 +- client/state/selectors/can-current-user.js | 10 +- client/state/selectors/count-post-likes.js | 4 +- .../selectors/edited-post-has-content.js | 27 +- .../eligible-for-free-to-paid-upsell.js | 23 +- ...et-account-recovery-reset-options-error.js | 4 +- .../get-account-recovery-reset-options.js | 4 +- .../get-account-recovery-reset-user-data.js | 2 +- .../selectors/get-billing-transactions.js | 16 +- client/state/selectors/get-blocked-sites.js | 4 +- client/state/selectors/get-follow-count.js | 4 +- .../get-image-editor-original-aspect-ratio.js | 4 +- .../get-jetpack-connection-status.js | 4 +- .../selectors/get-jetpack-jumpstart-status.js | 4 +- client/state/selectors/get-jetpack-module.js | 4 +- ...et-jetpack-modules-requiring-connection.js | 18 +- client/state/selectors/get-jetpack-modules.js | 4 +- client/state/selectors/get-jetpack-setting.js | 4 +- .../get-jetpack-settings-save-error.js | 4 +- ...et-jetpack-settings-save-request-status.js | 4 +- .../state/selectors/get-jetpack-settings.js | 4 +- client/state/selectors/get-media-item.js | 12 +- client/state/selectors/get-media-url.js | 12 +- client/state/selectors/get-media.js | 12 +- client/state/selectors/get-menu-item-types.js | 180 +- .../selectors/get-past-billing-transaction.js | 8 +- .../get-past-billing-transactions.js | 4 +- client/state/selectors/get-post-likes.js | 4 +- client/state/selectors/get-raw-offsets.js | 4 +- .../selectors/get-reader-followed-tags.js | 12 +- client/state/selectors/get-reader-tags.js | 4 +- client/state/selectors/get-reader-teams.js | 4 +- client/state/selectors/get-sharing-buttons.js | 4 +- client/state/selectors/get-site-gmt-offset.js | 6 +- client/state/selectors/get-site-icon-id.js | 26 +- client/state/selectors/get-site-icon-url.js | 18 +- client/state/selectors/get-site-setting.js | 4 +- .../selectors/get-site-stats-query-date.js | 6 +- .../selectors/get-site-stats-view-summary.js | 74 +- .../state/selectors/get-site-timezone-name.js | 26 +- .../selectors/get-site-timezone-value.js | 6 +- .../selectors/get-timezones-by-continent.js | 6 +- client/state/selectors/get-timezones-label.js | 6 +- .../get-timezones-labels-by-continent.js | 22 +- .../state/selectors/get-timezones-labels.js | 4 +- client/state/selectors/get-timezones.js | 21 +- .../get-upcoming-billing-transactions.js | 4 +- client/state/selectors/get-visible-sites.js | 8 +- .../has-broken-site-user-connection.js | 4 +- ...is-account-recovery-reset-options-ready.js | 6 +- .../is-activating-jetpack-jumpstart.js | 4 +- .../selectors/is-activating-jetpack-module.js | 4 +- .../selectors/is-automated-transfer-active.js | 14 +- .../is-deactivating-jetpack-jumpstart.js | 4 +- .../is-deactivating-jetpack-module.js | 4 +- client/state/selectors/is-directly-failed.js | 4 +- client/state/selectors/is-directly-ready.js | 4 +- .../selectors/is-directly-uninitialized.js | 4 +- client/state/selectors/is-domain-only-site.js | 14 +- .../selectors/is-fetching-jetpack-modules.js | 4 +- .../selectors/is-jetpack-module-active.js | 4 +- ...-module-unavailable-in-development-mode.js | 16 +- .../is-jetpack-settings-save-failure.js | 4 +- .../is-jetpack-site-in-development-mode.js | 4 +- .../is-jetpack-site-in-staging-mode.js | 4 +- .../state/selectors/is-mapped-domain-site.js | 14 +- client/state/selectors/is-private-site.js | 24 +- .../state/selectors/is-publicize-enabled.js | 8 +- .../selectors/is-reader-card-expanded.js | 6 +- .../is-regenerating-jetpack-post-by-email.js | 4 +- ...questing-account-recovery-reset-options.js | 4 +- .../is-requesting-billing-transactions.js | 4 +- ...is-requesting-jetpack-connection-status.js | 4 +- .../is-requesting-jetpack-jumpstart-status.js | 4 +- .../is-requesting-jetpack-settings.js | 4 +- .../selectors/is-requesting-media-item.js | 4 +- client/state/selectors/is-requesting-media.js | 12 +- .../selectors/is-requesting-post-likes.js | 4 +- .../selectors/is-requesting-reader-teams.js | 4 +- .../is-requesting-sharing-buttons.js | 4 +- .../selectors/is-requesting-timezones.js | 4 +- .../selectors/is-saving-sharing-buttons.js | 4 +- .../is-sending-billing-receipt-email.js | 4 +- .../is-sharing-buttons-save-successful.js | 4 +- .../selectors/is-site-automated-transfer.js | 4 +- client/state/selectors/is-site-blocked.js | 4 +- .../state/selectors/is-site-on-free-plan.js | 12 +- .../is-site-supporting-image-editor.js | 8 +- client/state/selectors/is-transient-media.js | 4 +- .../selectors/is-updating-jetpack-settings.js | 4 +- .../is-user-registration-days-within-range.js | 14 +- .../test/are-site-permalinks-editable.js | 89 +- .../state/selectors/test/can-current-user.js | 80 +- .../state/selectors/test/count-post-likes.js | 92 +- .../selectors/test/edited-post-has-content.js | 450 +- .../test/eligible-for-free-to-paid-upsell.js | 110 +- .../test/fixtures/jetpack-connection.js | 44 +- .../test/fixtures/jetpack-jumpstart.js | 34 +- .../test/fixtures/jetpack-modules.js | 132 +- .../test/fixtures/jetpack-settings.js | 60 +- ...et-account-recovery-reset-options-error.js | 56 +- .../get-account-recovery-reset-options.js | 48 +- .../get-account-recovery-reset-user-data.js | 36 +- .../test/get-billing-transactions.js | 100 +- .../state/selectors/test/get-blocked-sites.js | 32 +- .../state/selectors/test/get-follow-count.js | 56 +- .../get-image-editor-original-aspect-ratio.js | 52 +- .../test/get-jetpack-connection-status.js | 52 +- .../test/get-jetpack-jumpstart-status.js | 52 +- .../selectors/test/get-jetpack-module.js | 88 +- ...et-jetpack-modules-requiring-connection.js | 76 +- .../selectors/test/get-jetpack-modules.js | 60 +- .../selectors/test/get-jetpack-setting.js | 90 +- .../test/get-jetpack-settings-save-error.js | 82 +- ...et-jetpack-settings-save-request-status.js | 108 +- .../selectors/test/get-jetpack-settings.js | 56 +- client/state/selectors/test/get-media-item.js | 52 +- client/state/selectors/test/get-media-url.js | 64 +- client/state/selectors/test/get-media.js | 94 +- .../selectors/test/get-menu-item-types.js | 261 +- .../test/get-past-billing-transaction.js | 85 +- .../test/get-past-billing-transactions.js | 76 +- client/state/selectors/test/get-post-likes.js | 96 +- .../state/selectors/test/get-raw-offsets.js | 64 +- .../selectors/test/get-sharing-buttons.js | 56 +- .../selectors/test/get-site-gmt-offset.js | 70 +- .../state/selectors/test/get-site-icon-id.js | 154 +- .../state/selectors/test/get-site-icon-url.js | 141 +- .../state/selectors/test/get-site-setting.js | 34 +- .../test/get-site-stats-query-date.js | 70 +- .../test/get-site-stats-view-summary.js | 163 +- .../selectors/test/get-site-timezone-name.js | 128 +- .../selectors/test/get-site-timezone-value.js | 96 +- .../test/get-timezones-by-continent.js | 115 +- .../selectors/test/get-timezones-label.js | 98 +- .../test/get-timezones-labels-by-continent.js | 126 +- .../selectors/test/get-timezones-labels.js | 64 +- client/state/selectors/test/get-timezones.js | 91 +- .../test/get-upcoming-billing-transactions.js | 76 +- .../state/selectors/test/get-visible-sites.js | 112 +- .../test/has-broken-site-user-connection.js | 98 +- client/state/selectors/test/index.js | 58 +- ...is-account-recovery-reset-options-ready.js | 104 +- .../test/is-activating-jetpack-jumpstart.js | 76 +- .../test/is-activating-jetpack-module.js | 76 +- .../test/is-automated-transfer-active.js | 32 +- .../test/is-deactivating-jetpack-jumpstart.js | 76 +- .../test/is-deactivating-jetpack-module.js | 76 +- .../selectors/test/is-directly-failed.js | 44 +- .../state/selectors/test/is-directly-ready.js | 44 +- .../test/is-directly-uninitialized.js | 44 +- .../selectors/test/is-domain-only-site.js | 99 +- .../test/is-fetching-jetpack-modules.js | 76 +- .../test/is-jetpack-module-active.js | 76 +- ...-module-unavailable-in-development-mode.js | 148 +- .../test/is-jetpack-settings-save-failure.js | 82 +- .../is-jetpack-site-in-development-mode.js | 76 +- .../test/is-jetpack-site-in-staging-mode.js | 76 +- .../selectors/test/is-mapped-domain-site.js | 99 +- .../state/selectors/test/is-private-site.js | 201 +- .../selectors/test/is-publicize-enabled.js | 143 +- .../is-regenerating-jetpack-post-by-email.js | 76 +- ...questing-account-recovery-reset-options.js | 28 +- .../is-requesting-billing-transactions.js | 48 +- ...is-requesting-jetpack-connection-status.js | 76 +- .../is-requesting-jetpack-jumpstart-status.js | 76 +- .../test/is-requesting-jetpack-settings.js | 76 +- .../test/is-requesting-media-item.js | 58 +- .../selectors/test/is-requesting-media.js | 70 +- .../test/is-requesting-post-likes.js | 124 +- .../test/is-requesting-reader-teams.js | 44 +- .../test/is-requesting-sharing-buttons.js | 82 +- .../test/is-saving-sharing-buttons.js | 82 +- .../test/is-sending-billing-receipt-email.js | 70 +- .../is-sharing-buttons-save-successful.js | 82 +- .../state/selectors/test/is-site-blocked.js | 34 +- .../selectors/test/is-site-on-free-plan.js | 53 +- .../test/is-site-supporting-image-editor.js | 173 +- .../selectors/test/is-transient-media.js | 88 +- .../test/is-updating-jetpack-settings.js | 76 +- .../is-user-registration-days-within-range.js | 94 +- client/state/sharing/keyring/actions.js | 61 +- client/state/sharing/keyring/reducer.js | 70 +- client/state/sharing/keyring/schema.js | 52 +- client/state/sharing/keyring/selectors.js | 25 +- client/state/sharing/keyring/test/actions.js | 162 +- client/state/sharing/keyring/test/reducer.js | 402 +- .../state/sharing/keyring/test/selectors.js | 251 +- client/state/sharing/publicize/actions.js | 300 +- client/state/sharing/publicize/reducer.js | 181 +- client/state/sharing/publicize/schema.js | 58 +- client/state/sharing/publicize/selectors.js | 69 +- .../state/sharing/publicize/test/actions.js | 614 +- .../state/sharing/publicize/test/reducer.js | 738 +- .../state/sharing/publicize/test/selectors.js | 837 +- client/state/sharing/reducer.js | 10 +- client/state/sharing/selectors.js | 62 +- client/state/sharing/services/actions.js | 49 +- client/state/sharing/services/reducer.js | 36 +- client/state/sharing/services/schema.js | 60 +- client/state/sharing/services/selectors.js | 65 +- client/state/sharing/services/test/actions.js | 144 +- client/state/sharing/services/test/reducer.js | 262 +- .../state/sharing/services/test/selectors.js | 394 +- client/state/sharing/test/selectors.js | 144 +- client/state/shortcodes/actions.js | 69 +- client/state/shortcodes/reducer.js | 67 +- client/state/shortcodes/schema.js | 34 +- client/state/shortcodes/selectors.js | 8 +- client/state/shortcodes/test/actions.js | 188 +- client/state/shortcodes/test/reducer.js | 751 +- client/state/shortcodes/test/selectors.js | 214 +- .../state/signup/dependency-store/reducer.js | 26 +- .../state/signup/dependency-store/schema.js | 68 +- .../signup/dependency-store/selectors.js | 4 +- .../signup/dependency-store/test/reducer.js | 41 +- .../signup/dependency-store/test/selectors.js | 29 +- .../signup/optional-dependencies/reducer.js | 26 +- .../signup/optional-dependencies/schema.js | 2 +- .../signup/optional-dependencies/selectors.js | 4 +- .../optional-dependencies/test/selectors.js | 26 +- client/state/signup/reducer.js | 10 +- client/state/signup/steps/reducer.js | 8 +- .../state/signup/steps/site-title/actions.js | 10 +- .../state/signup/steps/site-title/reducer.js | 26 +- .../state/signup/steps/site-title/schema.js | 2 +- .../signup/steps/site-title/selectors.js | 4 +- .../signup/steps/site-title/test/reducer.js | 25 +- .../signup/steps/site-title/test/selectors.js | 30 +- client/state/signup/steps/survey/actions.js | 10 +- client/state/signup/steps/survey/reducer.js | 36 +- client/state/signup/steps/survey/schema.js | 12 +- client/state/signup/steps/survey/selectors.js | 12 +- .../state/signup/steps/survey/test/reducer.js | 70 +- .../signup/steps/survey/test/selectors.js | 98 +- client/state/site-roles/actions.js | 59 +- client/state/site-roles/reducer.js | 39 +- client/state/site-roles/schema.js | 44 +- client/state/site-roles/selectors.js | 8 +- client/state/site-roles/test/actions.js | 178 +- client/state/site-roles/test/reducer.js | 403 +- client/state/site-roles/test/selectors.js | 147 +- client/state/site-settings/actions.js | 142 +- .../state/site-settings/exporter/actions.js | 268 +- .../state/site-settings/exporter/constants.js | 10 +- .../state/site-settings/exporter/reducers.js | 254 +- .../state/site-settings/exporter/selectors.js | 140 +- .../site-settings/exporter/test/actions.js | 450 +- .../site-settings/exporter/test/data/index.js | 64 +- .../site-settings/exporter/test/reducer.js | 396 +- .../site-settings/exporter/test/selectors.js | 193 +- client/state/site-settings/reducer.js | 121 +- client/state/site-settings/schema.js | 16 +- client/state/site-settings/selectors.js | 24 +- client/state/site-settings/test/actions.js | 308 +- client/state/site-settings/test/reducer.js | 668 +- client/state/site-settings/test/selectors.js | 506 +- client/state/site-settings/test/utils.js | 40 +- client/state/site-settings/utils.js | 25 +- client/state/sites/actions.js | 251 +- client/state/sites/domains/actions.js | 100 +- client/state/sites/domains/assembler.js | 60 +- client/state/sites/domains/reducer.js | 116 +- client/state/sites/domains/schema.js | 82 +- client/state/sites/domains/selectors.js | 62 +- client/state/sites/domains/test/actions.js | 180 +- client/state/sites/domains/test/fixture.js | 314 +- client/state/sites/domains/test/reducer.js | 447 +- client/state/sites/domains/test/selectors.js | 110 +- client/state/sites/enhancer.js | 67 +- client/state/sites/guided-transfer/actions.js | 135 +- client/state/sites/guided-transfer/reducer.js | 120 +- client/state/sites/guided-transfer/schema.js | 42 +- .../state/sites/guided-transfer/selectors.js | 104 +- .../sites/guided-transfer/test/actions.js | 302 +- .../sites/guided-transfer/test/reducer.js | 338 +- .../sites/guided-transfer/test/selectors.js | 395 +- client/state/sites/media-storage/actions.js | 65 +- client/state/sites/media-storage/reducer.js | 83 +- client/state/sites/media-storage/schema.js | 26 +- client/state/sites/media-storage/selectors.js | 26 +- .../state/sites/media-storage/test/actions.js | 163 +- .../state/sites/media-storage/test/reducer.js | 446 +- .../sites/media-storage/test/selectors.js | 198 +- client/state/sites/plans/actions.js | 178 +- client/state/sites/plans/assembler.js | 70 +- client/state/sites/plans/reducer.js | 122 +- client/state/sites/plans/selectors.js | 199 +- client/state/sites/plans/test/actions.js | 25 +- client/state/sites/plans/test/reducer.js | 645 +- client/state/sites/plans/test/selectors.js | 1673 +- client/state/sites/reducer.js | 443 +- client/state/sites/schema.js | 124 +- client/state/sites/selectors.js | 976 +- client/state/sites/sharing-buttons/actions.js | 136 +- client/state/sites/sharing-buttons/reducer.js | 84 +- client/state/sites/sharing-buttons/schema.js | 22 +- .../sites/sharing-buttons/test/actions.js | 314 +- .../sites/sharing-buttons/test/reducer.js | 608 +- client/state/sites/test/actions.js | 472 +- client/state/sites/test/enhancer.js | 104 +- client/state/sites/test/reducer.js | 1408 +- client/state/sites/test/selectors.js | 5327 ++++--- client/state/sites/updates/actions.js | 44 +- client/state/sites/updates/reducer.js | 77 +- client/state/sites/updates/schema.js | 40 +- client/state/sites/updates/selectors.js | 9 +- client/state/sites/updates/utils.js | 50 +- client/state/sites/vouchers/actions.js | 172 +- client/state/sites/vouchers/reducer.js | 183 +- client/state/sites/vouchers/schema.js | 56 +- client/state/sites/vouchers/selectors.js | 40 +- client/state/sites/vouchers/service-types.js | 1 - client/state/sites/vouchers/test/actions.js | 410 +- client/state/sites/vouchers/test/fixture.js | 89 +- client/state/sites/vouchers/test/reducer.js | 1165 +- client/state/sites/vouchers/test/selectors.js | 82 +- client/state/stats/lists/actions.js | 89 +- client/state/stats/lists/constants.js | 48 +- client/state/stats/lists/reducer.js | 129 +- client/state/stats/lists/schema.js | 36 +- client/state/stats/lists/selectors.js | 187 +- client/state/stats/lists/test/actions.js | 205 +- client/state/stats/lists/test/reducer.js | 549 +- client/state/stats/lists/test/selectors.js | 1257 +- client/state/stats/lists/test/utils.js | 3366 ++-- client/state/stats/lists/utils.js | 1223 +- client/state/stats/posts/actions.js | 81 +- client/state/stats/posts/reducer.js | 94 +- client/state/stats/posts/schema.js | 30 +- client/state/stats/posts/selectors.js | 12 +- client/state/stats/posts/test/actions.js | 147 +- client/state/stats/posts/test/reducer.js | 636 +- client/state/stats/posts/test/selectors.js | 232 +- client/state/stats/reducer.js | 8 +- client/state/stored-cards/actions.js | 127 +- client/state/stored-cards/reducer.js | 134 +- client/state/stored-cards/schema.js | 42 +- client/state/stored-cards/selectors.js | 5 +- client/state/stored-cards/test/actions.js | 300 +- client/state/stored-cards/test/fixture.js | 60 +- client/state/stored-cards/test/reducer.js | 340 +- client/state/stored-cards/test/selectors.js | 82 +- client/state/support/actions.js | 64 +- client/state/support/reducer.js | 148 +- client/state/support/selectors.js | 1 - client/state/support/test/actions.js | 27 +- client/state/support/test/reducer.js | 141 +- client/state/terms/actions.js | 306 +- client/state/terms/constants.js | 18 +- client/state/terms/reducer.js | 165 +- client/state/terms/schema.js | 108 +- client/state/terms/selectors.js | 151 +- client/state/terms/test/actions.js | 921 +- client/state/terms/test/reducer.js | 582 +- client/state/terms/test/selectors.js | 1274 +- client/state/terms/test/utils.js | 96 +- client/state/terms/utils.js | 14 +- client/state/test/index.js | 98 +- client/state/test/initial-state.js | 764 +- client/state/test/mocks/schema.js | 20 +- client/state/test/utils.js | 728 +- client/state/themes/actions.js | 1166 +- client/state/themes/constants.js | 12 +- client/state/themes/reducer.js | 467 +- client/state/themes/schema.js | 193 +- client/state/themes/selectors.js | 517 +- client/state/themes/test/actions.js | 2150 +-- client/state/themes/test/reducer.js | 2181 +-- client/state/themes/test/selectors.js | 4923 +++--- client/state/themes/test/utils.js | 908 +- client/state/themes/themes-ui/reducer.js | 14 +- client/state/themes/themes-ui/selectors.js | 14 +- client/state/themes/themes-ui/test/reducer.js | 11 +- .../state/themes/themes-ui/test/selectors.js | 115 +- client/state/themes/upload-theme/reducer.js | 229 +- client/state/themes/upload-theme/selectors.js | 50 +- .../state/themes/upload-theme/test/reducer.js | 607 +- client/state/themes/utils.js | 272 +- client/state/timezones/actions.js | 36 +- client/state/timezones/reducer.js | 57 +- client/state/timezones/schema.js | 37 +- client/state/timezones/test/actions.js | 93 +- client/state/timezones/test/reducer.js | 742 +- client/state/ui/action-log/reducer.js | 53 +- client/state/ui/action-log/selectors.js | 8 +- client/state/ui/action-log/test/reducer.js | 93 +- client/state/ui/action-log/test/selectors.js | 110 +- client/state/ui/actions.js | 61 +- client/state/ui/editor/actions.js | 64 +- .../state/ui/editor/contact-form/actions.js | 62 +- .../state/ui/editor/contact-form/constants.js | 64 +- .../state/ui/editor/contact-form/reducer.js | 86 +- .../ui/editor/contact-form/test/actions.js | 108 +- .../ui/editor/contact-form/test/reducer.js | 814 +- .../state/ui/editor/image-editor/actions.js | 150 +- .../state/ui/editor/image-editor/constants.js | 18 +- .../state/ui/editor/image-editor/reducer.js | 286 +- .../state/ui/editor/image-editor/selectors.js | 28 +- .../ui/editor/image-editor/test/actions.js | 355 +- .../ui/editor/image-editor/test/reducer.js | 1035 +- .../ui/editor/image-editor/test/selectors.js | 312 +- client/state/ui/editor/last-draft/actions.js | 14 +- client/state/ui/editor/last-draft/reducer.js | 32 +- .../state/ui/editor/last-draft/selectors.js | 16 +- .../ui/editor/last-draft/test/actions.js | 44 +- .../ui/editor/last-draft/test/reducer.js | 85 +- .../ui/editor/last-draft/test/selectors.js | 183 +- client/state/ui/editor/reducer.js | 28 +- client/state/ui/editor/selectors.js | 56 +- client/state/ui/editor/test/actions.js | 98 +- client/state/ui/editor/test/reducer.js | 96 +- client/state/ui/editor/test/selectors.js | 516 +- client/state/ui/first-view/actions.js | 79 +- client/state/ui/first-view/constants.js | 14 +- client/state/ui/first-view/selectors.js | 176 +- client/state/ui/first-view/test/actions.js | 69 +- client/state/ui/first-view/test/selectors.js | 1246 +- client/state/ui/guided-tours/actions.js | 60 +- client/state/ui/guided-tours/contexts.js | 72 +- client/state/ui/guided-tours/reducer.js | 17 +- .../selectors/find-ongoing-tour.js | 5 +- .../state/ui/guided-tours/selectors/index.js | 284 +- client/state/ui/guided-tours/test/contexts.js | 178 +- .../ui/guided-tours/test/fixtures/config.js | 51 +- client/state/ui/guided-tours/test/reducer.js | 16 +- .../state/ui/guided-tours/test/selectors.js | 783 +- client/state/ui/happychat/actions.js | 17 +- client/state/ui/happychat/reducer.js | 35 +- client/state/ui/happychat/selectors.js | 8 +- client/state/ui/layout-focus/actions.js | 33 +- client/state/ui/layout-focus/reducer.js | 58 +- client/state/ui/layout-focus/selectors.js | 4 +- client/state/ui/layout-focus/test/actions.js | 40 +- client/state/ui/layout-focus/test/reducer.js | 148 +- .../state/ui/layout-focus/test/selectors.js | 32 +- client/state/ui/media-modal/actions.js | 12 +- client/state/ui/media-modal/constants.js | 8 +- client/state/ui/media-modal/reducer.js | 12 +- client/state/ui/media-modal/selectors.js | 4 +- client/state/ui/media-modal/test/actions.js | 40 +- client/state/ui/media-modal/test/reducer.js | 38 +- client/state/ui/media-modal/test/selectors.js | 28 +- client/state/ui/olark/actions.js | 81 +- client/state/ui/olark/reducer.js | 98 +- client/state/ui/olark/selectors.js | 26 +- client/state/ui/olark/test/actions.js | 208 +- client/state/ui/olark/test/reducer.js | 212 +- client/state/ui/olark/test/selectors.js | 319 +- client/state/ui/preview/actions.js | 66 +- client/state/ui/preview/reducer.js | 64 +- client/state/ui/preview/selectors.js | 12 +- client/state/ui/query-arguments/reducer.js | 44 +- .../ui/reader/card-expansions/actions.js | 29 +- .../ui/reader/card-expansions/reducer.js | 34 +- .../ui/reader/card-expansions/test/reducer.js | 61 +- client/state/ui/reader/reducer.js | 8 +- client/state/ui/reader/sidebar/actions.js | 26 +- client/state/ui/reader/sidebar/reducer.js | 37 +- client/state/ui/reducer.js | 111 +- client/state/ui/selectors.js | 78 +- client/state/ui/test/actions.js | 42 +- client/state/ui/test/reducer.js | 120 +- client/state/ui/test/selectors.js | 584 +- client/state/ui/theme-setup/actions.js | 53 +- client/state/ui/theme-setup/reducers.js | 33 +- client/state/users/actions.js | 10 +- client/state/users/reducer.js | 38 +- client/state/users/selectors.js | 4 +- client/state/users/suggestions/actions.js | 67 +- client/state/users/suggestions/reducer.js | 55 +- client/state/users/suggestions/schema.js | 42 +- client/state/users/suggestions/selectors.js | 8 +- .../state/users/suggestions/test/actions.js | 104 +- .../state/users/suggestions/test/reducer.js | 178 +- .../state/users/suggestions/test/selectors.js | 96 +- client/state/users/test/actions.js | 24 +- client/state/users/test/reducer.js | 202 +- client/state/users/test/selectors.js | 31 +- client/state/utils.js | 251 +- client/state/wordads/approve/actions.js | 78 +- client/state/wordads/approve/reducer.js | 118 +- client/state/wordads/approve/selectors.js | 42 +- client/state/wordads/approve/test/actions.js | 154 +- client/state/wordads/approve/test/reducer.js | 558 +- .../state/wordads/approve/test/selectors.js | 218 +- client/state/wordads/reducer.js | 8 +- client/state/wordads/status/actions.js | 50 +- client/state/wordads/status/reducer.js | 45 +- client/state/wordads/status/schema.js | 32 +- client/state/wordads/status/selectors.js | 8 +- client/state/wordads/status/test/reducer.js | 260 +- client/state/wordads/status/test/selectors.js | 84 +- client/support/support-user/index.jsx | 74 +- client/support/support-user/login-dialog.jsx | 263 +- client/wordpress-com.js | 614 +- index.js | 81 +- server/api/index.js | 28 +- server/api/oauth.js | 150 +- server/api/test/index.js | 211 +- server/boot/index.js | 145 +- server/build/index.js | 94 +- server/bundler/assets.js | 12 +- .../babel-loader-cache-identifier/index.js | 24 +- .../index.js | 202 +- .../test/index.js | 186 +- server/bundler/bin/bundler.js | 182 +- server/bundler/css-hot-reload.js | 255 +- server/bundler/hot-reloader.js | 118 +- server/bundler/index.js | 143 +- server/bundler/loader.js | 314 +- server/bundler/plugin.js | 92 +- server/bundler/utils.js | 40 +- server/bundler/webpack/stable-build-plugin.js | 225 +- server/config/index.js | 20 +- server/config/parser.js | 107 +- server/config/test/data/mocks.js | 142 +- server/config/test/parser.js | 164 +- server/config/validate-config-keys.js | 55 +- .../bin/generate-components-usage-stats.js | 265 +- .../devdocs/bin/generate-proptypes-index.js | 143 +- server/devdocs/index.js | 353 +- server/devdocs/selectors/index.js | 163 +- server/devdocs/test/index.js | 274 +- server/isomorphic-routing/index.js | 69 +- server/isomorphic-routing/loader.js | 64 +- server/pages/index.js | 680 +- server/pages/test/index.js | 37 +- server/render/index.js | 132 +- server/sanitize/index.js | 64 +- server/user-bootstrap/index.js | 108 +- server/user-bootstrap/shared-utils.js | 2 +- test/boot-test.js | 36 +- test/config.js | 2 +- test/load-suite.js | 26 +- test/run-mocha.js | 10 +- test/runner.js | 233 +- test/setup.js | 52 +- test/test/helpers/immutable-chai/index.js | 22 +- test/test/helpers/mocks/data-poller.js | 14 +- test/test/helpers/nock-control/index.js | 12 +- .../helpers/react/empty-component/index.jsx | 10 +- test/test/helpers/use-fake-dom/index.js | 19 +- .../helpers/use-filesystem-mocks/index.js | 48 +- test/test/helpers/use-mockery/index.js | 40 +- test/test/helpers/use-nock/index.js | 18 +- test/test/helpers/use-nock/test/index.js | 80 +- test/test/helpers/use-sinon/index.js | 68 +- webpack.config.js | 370 +- webpack.config.node.js | 237 +- 3424 files changed, 320027 insertions(+), 303435 deletions(-) mode change 100644 => 100755 bin/prettify-file.sh diff --git a/bin/prettify-file.sh b/bin/prettify-file.sh old mode 100644 new mode 100755 diff --git a/client/account-recovery/controller.js b/client/account-recovery/controller.js index 4eee82f18b621..0de829d67cbb8 100644 --- a/client/account-recovery/controller.js +++ b/client/account-recovery/controller.js @@ -17,73 +17,73 @@ import TransactionIdForm from 'account-recovery/reset-password/transaction-id-fo import ResetPasswordConfirmForm from 'account-recovery/reset-password/reset-password-confirm-form'; import { getCurrentUser } from 'state/current-user/selectors'; -export function lostPassword( context, next ) { - context.primary = ; - next(); +export function lostPassword(context, next) { + context.primary = ; + next(); } -export function forgotUsername( context, next ) { - context.primary = ; - next(); +export function forgotUsername(context, next) { + context.primary = ; + next(); } -export function resetPassword( context, next ) { - context.primary = ( - - - - ); +export function resetPassword(context, next) { + context.primary = ( + + + + ); - next(); + next(); } -export function resetPasswordSmsForm( context, next ) { - context.primary = ( - - - - ); +export function resetPasswordSmsForm(context, next) { + context.primary = ( + + + + ); - next(); + next(); } -export function resetPasswordEmailForm( context, next ) { - context.primary = ( - - - - ); +export function resetPasswordEmailForm(context, next) { + context.primary = ( + + + + ); - next(); + next(); } -export function resetPasswordByTransactionId( context, next ) { - context.primary = ( - - - - ); +export function resetPasswordByTransactionId(context, next) { + context.primary = ( + + + + ); - next(); + next(); } -export function resetPasswordConfirmForm( context, next ) { - context.primary = ( - - - - ); +export function resetPasswordConfirmForm(context, next) { + context.primary = ( + + + + ); - next(); + next(); } -export function redirectLoggedIn( context, next ) { - const currentUser = getCurrentUser( context.store.getState() ); +export function redirectLoggedIn(context, next) { + const currentUser = getCurrentUser(context.store.getState()); - if ( currentUser ) { - page.redirect( '/' ); - return; - } + if (currentUser) { + page.redirect('/'); + return; + } - next(); + next(); } diff --git a/client/account-recovery/forgot-username/forgot-username-form/index.jsx b/client/account-recovery/forgot-username/forgot-username-form/index.jsx index 42a65f1a176ad..49ad55701ed5e 100644 --- a/client/account-recovery/forgot-username/forgot-username-form/index.jsx +++ b/client/account-recovery/forgot-username/forgot-username-form/index.jsx @@ -15,131 +15,139 @@ import FormLabel from 'components/forms/form-label'; import FormInput from 'components/forms/form-text-input'; import { - fetchResetOptionsByNameAndUrl, - updatePasswordResetUserData, + fetchResetOptionsByNameAndUrl, + updatePasswordResetUserData, } from 'state/account-recovery/reset/actions'; import { - isRequestingAccountRecoveryResetOptions, - getAccountRecoveryResetUserData, - getAccountRecoveryResetOptionsError, + isRequestingAccountRecoveryResetOptions, + getAccountRecoveryResetUserData, + getAccountRecoveryResetOptionsError, } from 'state/selectors'; export class ForgotUsernameFormComponent extends Component { - submitForm = () => { - const { userData } = this.props; - - this.props.fetchResetOptionsByNameAndUrl( userData.firstName, userData.lastName, userData.url ); - }; - - firstNameUpdated = ( event ) => { - this.props.updatePasswordResetUserData( { firstName: event.target.value } ); - }; - - lastNameUpdated = ( event ) => { - this.props.updatePasswordResetUserData( { lastName: event.target.value } ); - }; - - siteUrlUpdated = ( event ) => { - this.props.updatePasswordResetUserData( { url: event.target.value } ); - }; - - getErrorMessage = ( requestError ) => { - const { translate } = this.props; - - if ( ! requestError ) { - return ''; - } - - if ( requestError.statusCode === 404 ) { - return translate( "We're not able to find an account matching that information. " + - 'Double-check your spelling, or try another name or URL.' ); - } - - return translate( "We've encountered some technical issues. Please try again later." ); - }; - - render() { - const { - translate, - userData, - isRequesting, - requestError, - } = this.props; - - const { - firstName = '', - lastName = '', - url = '', - } = userData; - - const isPrimaryButtonEnabled = firstName && lastName && url && ! isRequesting; - - return ( - -

- { translate( 'Forgot your username?' ) } -

-

{ translate( 'Enter your full name and URL instead.' ) }

- - { translate( 'First Name' ) } - - - - { translate( 'Last Name' ) } - - - - { translate( "Your site's URL" ) } - - - { - requestError && ( -

- { this.getErrorMessage( requestError ) } -

) - } - -
- ); - } + submitForm = () => { + const { userData } = this.props; + + this.props.fetchResetOptionsByNameAndUrl( + userData.firstName, + userData.lastName, + userData.url + ); + }; + + firstNameUpdated = event => { + this.props.updatePasswordResetUserData({ firstName: event.target.value }); + }; + + lastNameUpdated = event => { + this.props.updatePasswordResetUserData({ lastName: event.target.value }); + }; + + siteUrlUpdated = event => { + this.props.updatePasswordResetUserData({ url: event.target.value }); + }; + + getErrorMessage = requestError => { + const { translate } = this.props; + + if (!requestError) { + return ''; + } + + if (requestError.statusCode === 404) { + return translate( + "We're not able to find an account matching that information. " + + 'Double-check your spelling, or try another name or URL.' + ); + } + + return translate("We've encountered some technical issues. Please try again later."); + }; + + render() { + const { + translate, + userData, + isRequesting, + requestError, + } = this.props; + + const { + firstName = '', + lastName = '', + url = '', + } = userData; + + const isPrimaryButtonEnabled = firstName && lastName && url && !isRequesting; + + return ( + +

+ {translate('Forgot your username?')} +

+

{translate('Enter your full name and URL instead.')}

+ + {translate('First Name')} + + + + {translate('Last Name')} + + + + {translate("Your site's URL")} + + + {requestError && +

+ {this.getErrorMessage(requestError)} +

} + +
+ ); + } } ForgotUsernameFormComponent.defaultProps = { - isRequesting: false, - userData: {}, - requestError: null, - translate: identity, - fetchResetOptionsByNameAndUrl: noop, - updatePasswordResetUserData: noop, + isRequesting: false, + userData: {}, + requestError: null, + translate: identity, + fetchResetOptionsByNameAndUrl: noop, + updatePasswordResetUserData: noop, }; export default connect( - ( state ) => ( { - isRequesting: isRequestingAccountRecoveryResetOptions( state ), - userData: getAccountRecoveryResetUserData( state ), - requestError: getAccountRecoveryResetOptionsError( state ), - } ), - { - fetchResetOptionsByNameAndUrl, - updatePasswordResetUserData, - } -)( localize( ForgotUsernameFormComponent ) ); + state => ({ + isRequesting: isRequestingAccountRecoveryResetOptions(state), + userData: getAccountRecoveryResetUserData(state), + requestError: getAccountRecoveryResetOptionsError(state), + }), + { + fetchResetOptionsByNameAndUrl, + updatePasswordResetUserData, + } +)(localize(ForgotUsernameFormComponent)); diff --git a/client/account-recovery/forgot-username/forgot-username-form/test/index.jsx b/client/account-recovery/forgot-username/forgot-username-form/test/index.jsx index eadfefc383f3d..719955529cef5 100644 --- a/client/account-recovery/forgot-username/forgot-username-form/test/index.jsx +++ b/client/account-recovery/forgot-username/forgot-username-form/test/index.jsx @@ -11,121 +11,126 @@ import { shallow, mount } from 'enzyme'; import useFakeDom from 'test/helpers/use-fake-dom'; import { ForgotUsernameFormComponent } from '..'; -describe( 'ForgotUsername', () => { - const inputSelectors = [ - '.forgot-username-form__first-name-input', - '.forgot-username-form__last-name-input', - '.forgot-username-form__site-url-input', - ]; - - it( 'should render as expected', () => { - const wrapper = shallow( ); - - // Expect the fields to be enabled - inputSelectors.forEach( selector => { - expect( wrapper.find( selector ).prop( 'disabled' ) ).to.not.be.ok; - } ); - - expect( wrapper.find( '.forgot-username-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - context( 'fields', () => { - useFakeDom(); - - it( 'should be disabled when isRequesting is on', function() { - const wrapper = mount( - ); - - // Expect the fields to be disabled - inputSelectors.forEach( selector => { - expect( wrapper.find( selector ).prop( 'disabled' ) ).to.be.ok; - } ); - } ); - } ); - - context( 'submit button', () => { - useFakeDom(); - - it( 'should be disabled if firstName is blank', function() { - const wrapper = mount( - ); - - // Expect the button to be disabled - expect( wrapper.find( '.forgot-username-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - it( 'should be disabled if lastName is blank', function() { - const wrapper = mount( - ); - - // Expect the button to be disabled - expect( wrapper.find( '.forgot-username-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - it( 'should be disabled if url is blank', function() { - const wrapper = mount( - ); - - // Expect the button to be disabled - expect( wrapper.find( '.forgot-username-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - it( 'should be enabled when all fields are filled in', function() { - const wrapper = mount( - ); - - // Expect the button to be enabled - expect( wrapper.find( '.forgot-username-form__submit-button' ).prop( 'disabled' ) ).to.not.be.ok; - } ); - - it( 'should be disabled when submitted', function() { - const wrapper = mount( - ); - - inputSelectors.forEach( selector => { - expect( wrapper.find( selector ).prop( 'disabled' ) ).to.be.ok; - } ); - - expect( wrapper.find( '.forgot-username-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - } ); -} ); +describe('ForgotUsername', () => { + const inputSelectors = [ + '.forgot-username-form__first-name-input', + '.forgot-username-form__last-name-input', + '.forgot-username-form__site-url-input', + ]; + + it('should render as expected', () => { + const wrapper = shallow(); + + // Expect the fields to be enabled + inputSelectors.forEach(selector => { + expect(wrapper.find(selector).prop('disabled')).to.not.be.ok; + }); + + expect(wrapper.find('.forgot-username-form__submit-button').prop('disabled')).to.be.ok; + }); + + context('fields', () => { + useFakeDom(); + + it('should be disabled when isRequesting is on', function() { + const wrapper = mount( + + ); + + // Expect the fields to be disabled + inputSelectors.forEach(selector => { + expect(wrapper.find(selector).prop('disabled')).to.be.ok; + }); + }); + }); + + context('submit button', () => { + useFakeDom(); + + it('should be disabled if firstName is blank', function() { + const wrapper = mount( + + ); + + // Expect the button to be disabled + expect(wrapper.find('.forgot-username-form__submit-button').prop('disabled')).to.be.ok; + }); + + it('should be disabled if lastName is blank', function() { + const wrapper = mount( + + ); + + // Expect the button to be disabled + expect(wrapper.find('.forgot-username-form__submit-button').prop('disabled')).to.be.ok; + }); + + it('should be disabled if url is blank', function() { + const wrapper = mount( + + ); + + // Expect the button to be disabled + expect(wrapper.find('.forgot-username-form__submit-button').prop('disabled')).to.be.ok; + }); + + it('should be enabled when all fields are filled in', function() { + const wrapper = mount( + + ); + + // Expect the button to be enabled + expect( + wrapper.find('.forgot-username-form__submit-button').prop('disabled') + ).to.not.be.ok; + }); + + it('should be disabled when submitted', function() { + const wrapper = mount( + + ); + + inputSelectors.forEach(selector => { + expect(wrapper.find(selector).prop('disabled')).to.be.ok; + }); + + expect(wrapper.find('.forgot-username-form__submit-button').prop('disabled')).to.be.ok; + }); + }); +}); diff --git a/client/account-recovery/forgot-username/index.jsx b/client/account-recovery/forgot-username/index.jsx index 73c98b6c3ffc0..29b7ab04014b4 100644 --- a/client/account-recovery/forgot-username/index.jsx +++ b/client/account-recovery/forgot-username/index.jsx @@ -13,10 +13,10 @@ import Main from 'components/main'; import DocumentHead from 'components/data/document-head'; import ForgotUsernameForm from './forgot-username-form'; -export default localize( ( { className, translate, basePath } ) => ( -
- - - -
-) ); +export default localize(({ className, translate, basePath }) => ( +
+ + + +
+)); diff --git a/client/account-recovery/index.js b/client/account-recovery/index.js index df78a997ab2c4..d04e750a940f6 100644 --- a/client/account-recovery/index.js +++ b/client/account-recovery/index.js @@ -2,26 +2,38 @@ * Internal dependencies */ import { - lostPassword, - forgotUsername, - resetPassword, - resetPasswordSmsForm, - resetPasswordEmailForm, - resetPasswordByTransactionId, - resetPasswordConfirmForm, - redirectLoggedIn + lostPassword, + forgotUsername, + resetPassword, + resetPasswordSmsForm, + resetPasswordEmailForm, + resetPasswordByTransactionId, + resetPasswordConfirmForm, + redirectLoggedIn, } from './controller'; import config from 'config'; -export default function( router ) { - // Main route for account recovery is the lost password page - if ( config.isEnabled( 'account-recovery' ) ) { - router( '/account-recovery', redirectLoggedIn, lostPassword ); - router( '/account-recovery/forgot-username', redirectLoggedIn, forgotUsername ); - router( '/account-recovery/reset-password', redirectLoggedIn, resetPassword ); - router( '/account-recovery/reset-password/sms-form', redirectLoggedIn, resetPasswordSmsForm ); - router( '/account-recovery/reset-password/email-form', redirectLoggedIn, resetPasswordEmailForm ); - router( '/account-recovery/reset-password/transaction-id', redirectLoggedIn, resetPasswordByTransactionId ); - router( '/account-recovery/reset-password/confirm', redirectLoggedIn, resetPasswordConfirmForm ); - } +export default function(router) { + // Main route for account recovery is the lost password page + if (config.isEnabled('account-recovery')) { + router('/account-recovery', redirectLoggedIn, lostPassword); + router('/account-recovery/forgot-username', redirectLoggedIn, forgotUsername); + router('/account-recovery/reset-password', redirectLoggedIn, resetPassword); + router('/account-recovery/reset-password/sms-form', redirectLoggedIn, resetPasswordSmsForm); + router( + '/account-recovery/reset-password/email-form', + redirectLoggedIn, + resetPasswordEmailForm + ); + router( + '/account-recovery/reset-password/transaction-id', + redirectLoggedIn, + resetPasswordByTransactionId + ); + router( + '/account-recovery/reset-password/confirm', + redirectLoggedIn, + resetPasswordConfirmForm + ); + } } diff --git a/client/account-recovery/lost-password/index.jsx b/client/account-recovery/lost-password/index.jsx index e6511bfd1b36a..62d2d62d597d9 100644 --- a/client/account-recovery/lost-password/index.jsx +++ b/client/account-recovery/lost-password/index.jsx @@ -13,10 +13,10 @@ import Main from 'components/main'; import DocumentHead from 'components/data/document-head'; import LostPasswordForm from './lost-password-form'; -export default localize( ( { className, translate, basePath } ) => ( -
- - - -
-) ); +export default localize(({ className, translate, basePath }) => ( +
+ + + +
+)); diff --git a/client/account-recovery/lost-password/lost-password-form/index.jsx b/client/account-recovery/lost-password/lost-password-form/index.jsx index 946cf7edf7727..c202175b16c88 100644 --- a/client/account-recovery/lost-password/lost-password-form/index.jsx +++ b/client/account-recovery/lost-password/lost-password-form/index.jsx @@ -16,119 +16,123 @@ import FormLabel from 'components/forms/form-label'; import FormInput from 'components/forms/form-text-input'; import { - fetchResetOptionsByLogin, - updatePasswordResetUserData, + fetchResetOptionsByLogin, + updatePasswordResetUserData, } from 'state/account-recovery/reset/actions'; import { - isRequestingAccountRecoveryResetOptions, - getAccountRecoveryResetUserData, - getAccountRecoveryResetOptionsError, + isRequestingAccountRecoveryResetOptions, + getAccountRecoveryResetUserData, + getAccountRecoveryResetOptionsError, } from 'state/selectors'; export class LostPasswordFormComponent extends Component { - submitForm = () => { - this.props.fetchResetOptionsByLogin( this.props.userLogin ); - }; + submitForm = () => { + this.props.fetchResetOptionsByLogin(this.props.userLogin); + }; - onUserLoginChanged = ( event ) => { - this.props.updatePasswordResetUserData( { - user: event.target.value - } ); - }; + onUserLoginChanged = event => { + this.props.updatePasswordResetUserData({ + user: event.target.value, + }); + }; - render() { - const { - translate, - userLogin, - isRequesting, - requestError, - } = this.props; + render() { + const { + translate, + userLogin, + isRequesting, + requestError, + } = this.props; - const isPrimaryButtonDisabled = ! userLogin || isRequesting; + const isPrimaryButtonDisabled = !userLogin || isRequesting; - return ( -
- -

- { translate( 'Lost your password?' ) } -

-

{ translate( 'Follow these simple steps to reset your account:' ) }

-
    -
  1. - { translate( - 'Enter your {{strong}}WordPress.com{{/strong}} username or email address', - { components: { strong: } } - ) } -
  2. -
  3. - { translate( 'Choose a password reset method' ) } -
  4. -
  5. - { translate( - 'Follow instructions and be reunited with your {{strong}}WordPress.com{{/strong}} account', - { components: { strong: } } - ) } -
  6. -
-

- { translate( - 'Want more help? We have a full {{link}}guide to resetting your password{{/link}}.', - { components: { link: } } - ) } -

-
- - - { translate( 'Username or Email' ) } + return ( +
+ +

+ {translate('Lost your password?')} +

+

{translate('Follow these simple steps to reset your account:')}

+
    +
  1. + {translate( + 'Enter your {{strong}}WordPress.com{{/strong}} username or email address', + { components: { strong: } } + )} +
  2. +
  3. + {translate('Choose a password reset method')} +
  4. +
  5. + {translate( + 'Follow instructions and be reunited with your {{strong}}WordPress.com{{/strong}} account', + { components: { strong: } } + )} +
  6. +
+

+ {translate( + 'Want more help? We have a full {{link}}guide to resetting your password{{/link}}.', + { components: { link: } } + )} +

+ + + + {translate('Username or Email')} - - - { - requestError && ( -

- { translate( 'We encountered some problems with that login information. ' + - 'Please provide another one or try again later.' ) } -

) - } - -
- { translate( 'Forgot your username?' ) } - - -
- ); - } + + + {requestError && +

+ {translate( + 'We encountered some problems with that login information. ' + + 'Please provide another one or try again later.' + )} +

} + + + {translate('Forgot your username?')} + + +
+ ); + } } LostPasswordFormComponent.defaultProps = { - isRequesting: false, - userLogin: null, - requestError: null, - translate: identity, - fetchResetOptionsByLogin: noop, - updatePasswordResetUserData: noop, + isRequesting: false, + userLogin: null, + requestError: null, + translate: identity, + fetchResetOptionsByLogin: noop, + updatePasswordResetUserData: noop, }; export default connect( - ( state ) => ( { - isRequesting: isRequestingAccountRecoveryResetOptions( state ), - userLogin: getAccountRecoveryResetUserData( state ).user, - requestError: getAccountRecoveryResetOptionsError( state ), - } ), - { - fetchResetOptionsByLogin, - updatePasswordResetUserData, - } -)( localize( LostPasswordFormComponent ) ); + state => ({ + isRequesting: isRequestingAccountRecoveryResetOptions(state), + userLogin: getAccountRecoveryResetUserData(state).user, + requestError: getAccountRecoveryResetOptionsError(state), + }), + { + fetchResetOptionsByLogin, + updatePasswordResetUserData, + } +)(localize(LostPasswordFormComponent)); diff --git a/client/account-recovery/lost-password/lost-password-form/test/index.jsx b/client/account-recovery/lost-password/lost-password-form/test/index.jsx index 2679b6d13965b..3f05f3e3f1aea 100644 --- a/client/account-recovery/lost-password/lost-password-form/test/index.jsx +++ b/client/account-recovery/lost-password/lost-password-form/test/index.jsx @@ -11,30 +11,36 @@ import { shallow, mount } from 'enzyme'; import useFakeDom from 'test/helpers/use-fake-dom'; import { LostPasswordFormComponent } from '..'; -describe( 'LostPassword', () => { - it( 'should render as expected', () => { - const wrapper = shallow( ); - - expect( wrapper.find( '.lost-password-form__user-login-input' ).prop( 'disabled' ) ).to.not.be.ok; - expect( wrapper.find( '.lost-password-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - context( 'events', () => { - useFakeDom(); - - it( 'submit button should be disabled if user login is blank', function() { - const wrapper = mount( ); - - wrapper.find( '.lost-password-form__user-login-input' ).node.value = ''; - expect( wrapper.find( '.lost-password-form__user-login-input' ).prop( 'disabled' ) ).to.not.be.ok; - expect( wrapper.find( '.lost-password-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - it( 'should be disabled when isRequesting is true', function() { - const wrapper = mount( ); - - expect( wrapper.find( '.lost-password-form__user-login-input' ).prop( 'disabled' ) ).to.be.ok; - expect( wrapper.find( '.lost-password-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - } ); -} ); +describe('LostPassword', () => { + it('should render as expected', () => { + const wrapper = shallow(); + + expect(wrapper.find('.lost-password-form__user-login-input').prop('disabled')).to.not.be.ok; + expect(wrapper.find('.lost-password-form__submit-button').prop('disabled')).to.be.ok; + }); + + context('events', () => { + useFakeDom(); + + it('submit button should be disabled if user login is blank', function() { + const wrapper = mount( + + ); + + wrapper.find('.lost-password-form__user-login-input').node.value = ''; + expect( + wrapper.find('.lost-password-form__user-login-input').prop('disabled') + ).to.not.be.ok; + expect(wrapper.find('.lost-password-form__submit-button').prop('disabled')).to.be.ok; + }); + + it('should be disabled when isRequesting is true', function() { + const wrapper = mount( + + ); + + expect(wrapper.find('.lost-password-form__user-login-input').prop('disabled')).to.be.ok; + expect(wrapper.find('.lost-password-form__submit-button').prop('disabled')).to.be.ok; + }); + }); +}); diff --git a/client/account-recovery/reset-password/index.jsx b/client/account-recovery/reset-password/index.jsx index f9433fe225bda..bade1cf0c8fd6 100644 --- a/client/account-recovery/reset-password/index.jsx +++ b/client/account-recovery/reset-password/index.jsx @@ -12,10 +12,10 @@ import PageViewTracker from 'lib/analytics/page-view-tracker'; import Main from 'components/main'; import DocumentHead from 'components/data/document-head'; -export default localize( ( { className, translate, basePath, children } ) => ( -
- - - { children } -
-) ); +export default localize(({ className, translate, basePath, children }) => ( +
+ + + {children} +
+)); diff --git a/client/account-recovery/reset-password/reset-password-confirm-form/index.jsx b/client/account-recovery/reset-password/reset-password-confirm-form/index.jsx index c827c7aa6bade..9270070b19ac7 100644 --- a/client/account-recovery/reset-password/reset-password-confirm-form/index.jsx +++ b/client/account-recovery/reset-password/reset-password-confirm-form/index.jsx @@ -14,42 +14,56 @@ import FormLabel from 'components/forms/form-label'; import FormButton from 'components/forms/form-button'; import { STRONG_PASSWORD } from 'lib/url/support'; -const ResetPasswordConfirmForm = ( props ) => { - const { translate } = props; +const ResetPasswordConfirmForm = props => { + const { translate } = props; - return ( - -

{ translate( 'Reset your password' ) }

- - { translate( 'New password' ) } - - - - { translate( 'Generate strong password' ) } - -

- { translate( - '{{a}}Great passwords{{/a}} use upper and lower case characters, numbers, and symbols like {{em}}%(symbols)s{{/em}}.', - { - args: { - symbols: '!/"$%&', - }, - components: { - a: , - em: , - } - } - ) } -

- - { translate( 'Reset Password' ) } - -
- ); + return ( + +

+ {translate('Reset your password')} +

+ + {translate('New password')} + + + + {translate('Generate strong password')} + +

+ {translate( + '{{a}}Great passwords{{/a}} use upper and lower case characters, numbers, and symbols like {{em}}%(symbols)s{{/em}}.', + { + args: { + symbols: '!/"$%&', + }, + components: { + a: ( + + ), + em: , + }, + } + )} +

+ + {translate('Reset Password')} + + + ); }; ResetPasswordConfirmForm.defaultProps = { - translate: identity, + translate: identity, }; -export default localize( ResetPasswordConfirmForm ); +export default localize(ResetPasswordConfirmForm); diff --git a/client/account-recovery/reset-password/reset-password-email-form/index.jsx b/client/account-recovery/reset-password/reset-password-email-form/index.jsx index 4601b43c150b2..82d3cd8e61082 100644 --- a/client/account-recovery/reset-password/reset-password-email-form/index.jsx +++ b/client/account-recovery/reset-password/reset-password-email-form/index.jsx @@ -9,36 +9,36 @@ import { localize } from 'i18n-calypso'; */ import Card from 'components/card'; -const ResetPasswordEmailSent = ( props ) => { - const { - email, - translate, - } = props; +const ResetPasswordEmailSent = props => { + const { + email, + translate, + } = props; - return ( - -

- { translate( 'Reset your password' ) } -

-

- { translate( - "We've sent an email to {{strong}}%(email)s{{/strong}} with a link to complete your password reset.", - { - components: { strong: }, - args: { email } - } - ) } -

-

- { translate( "If you haven't received it, please check your spam or junk folder." ) } -

-
{ translate( "Didn't receive it?" ) } - - ); + return ( + +

+ {translate('Reset your password')} +

+

+ {translate( + "We've sent an email to {{strong}}%(email)s{{/strong}} with a link to complete your password reset.", + { + components: { strong: }, + args: { email }, + } + )} +

+

+ {translate("If you haven't received it, please check your spam or junk folder.")} +

+ {translate("Didn't receive it?")} +
+ ); }; ResetPasswordEmailSent.defaultProps = { - email: 'test@example.com', // TODO: Remove this default prop once this component is connected + email: 'test@example.com', // TODO: Remove this default prop once this component is connected }; -export default localize( ResetPasswordEmailSent ); +export default localize(ResetPasswordEmailSent); diff --git a/client/account-recovery/reset-password/reset-password-form/index.jsx b/client/account-recovery/reset-password/reset-password-form/index.jsx index d2676a4af0ff9..c5cb38d3c87f0 100644 --- a/client/account-recovery/reset-password/reset-password-form/index.jsx +++ b/client/account-recovery/reset-password/reset-password-form/index.jsx @@ -18,114 +18,112 @@ import ResetOptionSet from './reset-option-set'; import { getAccountRecoveryResetOptions } from 'state/selectors'; export class ResetPasswordFormComponent extends Component { - static defaultProps = { - translate: identity, - }; + static defaultProps = { + translate: identity, + }; - static propTypes = { - translate: PropTypes.func.isRequired, - resetOptions: PropTypes.array.isRequired, - }; + static propTypes = { + translate: PropTypes.func.isRequired, + resetOptions: PropTypes.array.isRequired, + }; - state = { - isSubmitting: false, - selectedResetOption: null, - }; + state = { + isSubmitting: false, + selectedResetOption: null, + }; - submitForm = () => { - // TODO: - // This is going to be replaced by corresponding redux actions. - this.setState( { isSubmitting: true } ); - }; + submitForm = () => { + // TODO: + // This is going to be replaced by corresponding redux actions. + this.setState({ isSubmitting: true }); + }; - onResetOptionChanged = ( event ) => { - this.setState( { selectedResetOption: event.currentTarget.value } ); - }; + onResetOptionChanged = event => { + this.setState({ selectedResetOption: event.currentTarget.value }); + }; - getOptionDisplayStrings = ( optionName ) => { - const { translate } = this.props; + getOptionDisplayStrings = optionName => { + const { translate } = this.props; - switch ( optionName ) { - case 'primary': - return { - email: translate( - 'Email a reset link to {{strong}}your main email address{{/strong}}', - { components: { strong: } } - ), - sms: translate( - 'Send a reset code to {{strong}}your main phone{{/strong}}', - { components: { strong: } } - ), - }; - case 'secondary': - return { - email: translate( - 'Email a reset link to {{strong}}your recovery email address{{/strong}}', - { components: { strong: } } - ), - sms: translate( - 'Send a reset code to {{strong}}your recovery phone{{/strong}}', - { components: { strong: } } - ), - }; - default: - return {}; - } - }; + switch (optionName) { + case 'primary': + return { + email: translate( + 'Email a reset link to {{strong}}your main email address{{/strong}}', + { components: { strong: } } + ), + sms: translate('Send a reset code to {{strong}}your main phone{{/strong}}', { + components: { strong: }, + }), + }; + case 'secondary': + return { + email: translate( + 'Email a reset link to {{strong}}your recovery email address{{/strong}}', + { components: { strong: } } + ), + sms: translate( + 'Send a reset code to {{strong}}your recovery phone{{/strong}}', + { components: { strong: } } + ), + }; + default: + return {}; + } + }; - render() { - const { - resetOptions, - translate - } = this.props; + render() { + const { + resetOptions, + translate, + } = this.props; - const { isSubmitting, selectedResetOption } = this.state; - const isPrimaryButtonEnabled = selectedResetOption && ! isSubmitting; + const { isSubmitting, selectedResetOption } = this.state; + const isPrimaryButtonEnabled = selectedResetOption && !isSubmitting; - return ( -
-

- { translate( 'Reset your password' ) } -

-

- { translate( - 'To reset your password and recover access to your account, ' + - 'select one of these options and follow the instructions.' - ) } -

- - - - { translate( 'How would you like to reset your password?' ) } - - { resetOptions.map( ( { email, sms, name }, index ) => ( - - ) ) } - - - -
- ); - } + return ( +
+

+ {translate('Reset your password')} +

+

+ {translate( + 'To reset your password and recover access to your account, ' + + 'select one of these options and follow the instructions.' + )} +

+ + + + {translate('How would you like to reset your password?')} + + {resetOptions.map(({ email, sms, name }, index) => ( + + ))} + + + +
+ ); + } } -export default connect( - ( state ) => ( { - resetOptions: getAccountRecoveryResetOptions( state ), - } ) -)( localize( ResetPasswordFormComponent ) ); +export default connect(state => ({ + resetOptions: getAccountRecoveryResetOptions(state), +}))(localize(ResetPasswordFormComponent)); diff --git a/client/account-recovery/reset-password/reset-password-form/reset-option-set.jsx b/client/account-recovery/reset-password/reset-password-form/reset-option-set.jsx index c3ea9a189c638..c81ca91f7bbbf 100644 --- a/client/account-recovery/reset-password/reset-password-form/reset-option-set.jsx +++ b/client/account-recovery/reset-password/reset-password-form/reset-option-set.jsx @@ -10,46 +10,46 @@ import classnames from 'classnames'; import FormLabel from 'components/forms/form-label'; import FormRadio from 'components/forms/form-radio'; -const ResetOptionSet = ( props ) => { - const { - email, - sms, - name, - displayStrings, - disabled, - onOptionChanged, - selectedResetOption, - } = props; +const ResetOptionSet = props => { + const { + email, + sms, + name, + displayStrings, + disabled, + onOptionChanged, + selectedResetOption, + } = props; - const emailFieldValue = name + '_email'; - const smsFieldValue = name + '_sms'; + const emailFieldValue = name + '_email'; + const smsFieldValue = name + '_sms'; - return ( -
- { email && ( - - - { displayStrings.email } - ) - } - { sms && ( - - - { displayStrings.sms } - ) - } -
- ); + return ( +
+ {email && + + + {displayStrings.email} + } + {sms && + + + {displayStrings.sms} + } +
+ ); }; export default ResetOptionSet; diff --git a/client/account-recovery/reset-password/reset-password-form/test/index.jsx b/client/account-recovery/reset-password/reset-password-form/test/index.jsx index 38c74237f6f8f..c24f9032ca5df 100644 --- a/client/account-recovery/reset-password/reset-password-form/test/index.jsx +++ b/client/account-recovery/reset-password/reset-password-form/test/index.jsx @@ -12,91 +12,83 @@ import useFakeDom from 'test/helpers/use-fake-dom'; import { ResetPasswordFormComponent } from '..'; import ResetOptionSet from '../reset-option-set'; -describe( 'ResetPasswordForm', () => { - const exampleResetOptions = [ - { - email: 'test@example.com', - sms: '+15555555555', - name: 'primary', - }, - { - email: 'test2@example.com', - sms: '+16666666666', - name: 'secondary', - }, - ]; - - const inputSelectors = [ - '.reset-password-form__email-option.primary', - '.reset-password-form__email-option.secondary', - '.reset-password-form__sms-option.primary', - '.reset-password-form__sms-option.secondary', - ]; - - it( 'should render as expected', () => { - const wrapper = shallow( - - ); - - expect( wrapper ).to.have.state( 'isSubmitting' ).to.be.false; - expect( wrapper.find( ResetOptionSet ) ).to.have.length( 2 ); - - expect( wrapper.find( '.reset-password-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - context( 'fields', () => { - useFakeDom(); - - it( 'should be disabled while submitting', function() { - const wrapper = mount( - - ); - wrapper.find( '.reset-password-form__email-option.primary' ).simulate( 'change' ); - - // Expect the button to be enabled - expect( wrapper.find( '.reset-password-form__submit-button' ).prop( 'disabled' ) ).to.not.be.ok; - - wrapper.find( '.reset-password-form__submit-button' ).simulate( 'click' ); - - expect( wrapper ).to.have.state( 'isSubmitting' ).to.be.true; - - // Expect the fields to be disabled - inputSelectors.forEach( selector => { - expect( wrapper.find( selector ).prop( 'disabled' ) ).to.be.ok; - } ); - } ); - } ); - - context( 'submit button', () => { - useFakeDom(); - - it( 'should be disabled if no reset option is selected', function() { - const wrapper = mount( - - ); - - // Expect the button to be disabled - expect( wrapper.find( '.reset-password-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - it( 'should be disabled when clicked', function() { - const wrapper = mount( - - ); - - wrapper.find( '.reset-password-form__email-option.primary' ).simulate( 'click' ); - wrapper.find( '.reset-password-form__submit-button' ).simulate( 'click' ); - - expect( wrapper ).to.have.state( 'isSubmitting' ).to.be.true; - expect( wrapper.find( '.reset-password-form__submit-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - } ); -} ); +describe('ResetPasswordForm', () => { + const exampleResetOptions = [ + { + email: 'test@example.com', + sms: '+15555555555', + name: 'primary', + }, + { + email: 'test2@example.com', + sms: '+16666666666', + name: 'secondary', + }, + ]; + + const inputSelectors = [ + '.reset-password-form__email-option.primary', + '.reset-password-form__email-option.secondary', + '.reset-password-form__sms-option.primary', + '.reset-password-form__sms-option.secondary', + ]; + + it('should render as expected', () => { + const wrapper = shallow(); + + expect(wrapper).to.have.state('isSubmitting').to.be.false; + expect(wrapper.find(ResetOptionSet)).to.have.length(2); + + expect(wrapper.find('.reset-password-form__submit-button').prop('disabled')).to.be.ok; + }); + + context('fields', () => { + useFakeDom(); + + it('should be disabled while submitting', function() { + const wrapper = mount( + + ); + wrapper.find('.reset-password-form__email-option.primary').simulate('change'); + + // Expect the button to be enabled + expect( + wrapper.find('.reset-password-form__submit-button').prop('disabled') + ).to.not.be.ok; + + wrapper.find('.reset-password-form__submit-button').simulate('click'); + + expect(wrapper).to.have.state('isSubmitting').to.be.true; + + // Expect the fields to be disabled + inputSelectors.forEach(selector => { + expect(wrapper.find(selector).prop('disabled')).to.be.ok; + }); + }); + }); + + context('submit button', () => { + useFakeDom(); + + it('should be disabled if no reset option is selected', function() { + const wrapper = mount( + + ); + + // Expect the button to be disabled + expect(wrapper.find('.reset-password-form__submit-button').prop('disabled')).to.be.ok; + }); + + it('should be disabled when clicked', function() { + const wrapper = mount( + + ); + + wrapper.find('.reset-password-form__email-option.primary').simulate('click'); + wrapper.find('.reset-password-form__submit-button').simulate('click'); + + expect(wrapper).to.have.state('isSubmitting').to.be.true; + expect(wrapper.find('.reset-password-form__submit-button').prop('disabled')).to.be.ok; + }); + }); +}); diff --git a/client/account-recovery/reset-password/reset-password-sms-form/index.jsx b/client/account-recovery/reset-password/reset-password-sms-form/index.jsx index e0848d1ed1807..a24916927741d 100644 --- a/client/account-recovery/reset-password/reset-password-sms-form/index.jsx +++ b/client/account-recovery/reset-password/reset-password-sms-form/index.jsx @@ -12,32 +12,33 @@ import FormTextInput from 'components/forms/form-text-input'; import FormButton from 'components/forms/form-button'; class ResetPasswordSmsForm extends Component { - render() { - const { - translate, - } = this.props; + render() { + const { + translate, + } = this.props; - return ( - -

- { translate( 'Reset your password' ) } -

-

- { translate( 'Please enter the code you were sent by SMS. ' + - 'It will look something like {{code}}63423423{{/code}}. You may need to wait a few moments before it arrives.', - { components: { code: } } ) - } -

- - - { translate( 'Continue' ) } - - - { translate( 'No SMS?' ) } - -
- ); - } + return ( + +

+ {translate('Reset your password')} +

+

+ {translate( + 'Please enter the code you were sent by SMS. ' + + 'It will look something like {{code}}63423423{{/code}}. You may need to wait a few moments before it arrives.', + { components: { code: } } + )} +

+ + + {translate('Continue')} + + + {translate('No SMS?')} + +
+ ); + } } -export default localize( ResetPasswordSmsForm ); +export default localize(ResetPasswordSmsForm); diff --git a/client/account-recovery/reset-password/transaction-id-form/index.jsx b/client/account-recovery/reset-password/transaction-id-form/index.jsx index 5ad870ee99803..3abdb4b3b7c91 100644 --- a/client/account-recovery/reset-password/transaction-id-form/index.jsx +++ b/client/account-recovery/reset-password/transaction-id-form/index.jsx @@ -15,90 +15,91 @@ import FormLabel from 'components/forms/form-label'; import FormInput from 'components/forms/form-text-input'; export class TransactionIdFormComponent extends Component { - static defaultProps = { - translate: identity, - }; + static defaultProps = { + translate: identity, + }; - state = { - isSubmitting: false, - transactionId: '', - } + state = { + isSubmitting: false, + transactionId: '', + }; - submitForm = () => { - this.setState( { isSubmitting: true } ); - }; + submitForm = () => { + this.setState({ isSubmitting: true }); + }; - onTransactionIdChanged = ( event ) => { - this.setState( { transactionId: event.target.value } ); - }; + onTransactionIdChanged = event => { + this.setState({ transactionId: event.target.value }); + }; - render() { - const { translate } = this.props; - const { isSubmitting, transactionId } = this.state; - const isPrimaryButtonDisabled = ! transactionId || isSubmitting; + render() { + const { translate } = this.props; + const { isSubmitting, transactionId } = this.state; + const isPrimaryButtonDisabled = !transactionId || isSubmitting; - return ( -
-

- { translate( 'Account recovery' ) } -

-

- { translate( - 'Please provide the following information to verify your identity. ' + - 'Without {{strong}}proper validating information{{/strong}}, ' + - 'we might not be able to help you recover your account. ' + - 'Read more about the process {{helpLink}}here{{/helpLink}}.', - { - components: { - strong: , - helpLink: - } - } - ) } -

- - - { translate( 'Transaction ID' ) } - -

- { translate( - 'If you have purchased any upgrades on WordPress.com, this number ' + - 'will be in your receipt from PayPal or in your PayPal account. ' + - '{{helpLink}}Need help to find your transaction id?{{/helpLink}}', - { - components: { - helpLink: - } - } - ) } -

- + return ( +
+

+ {translate('Account recovery')} +

+

+ {translate( + 'Please provide the following information to verify your identity. ' + + 'Without {{strong}}proper validating information{{/strong}}, ' + + 'we might not be able to help you recover your account. ' + + 'Read more about the process {{helpLink}}here{{/helpLink}}.', + { + components: { + strong: , + helpLink: , + }, + } + )} +

+ + + {translate('Transaction ID')} + +

+ {translate( + 'If you have purchased any upgrades on WordPress.com, this number ' + + 'will be in your receipt from PayPal or in your PayPal account. ' + + '{{helpLink}}Need help to find your transaction id?{{/helpLink}}', + { + components: { + helpLink: , + }, + } + )} +

+ - + - - -
- ); - } + + +
+ ); + } } -export default localize( TransactionIdFormComponent ); +export default localize(TransactionIdFormComponent); diff --git a/client/account-recovery/reset-password/transaction-id-form/test/index.jsx b/client/account-recovery/reset-password/transaction-id-form/test/index.jsx index 487eee7d90a42..fd774e4a45fb8 100644 --- a/client/account-recovery/reset-password/transaction-id-form/test/index.jsx +++ b/client/account-recovery/reset-password/transaction-id-form/test/index.jsx @@ -11,38 +11,44 @@ import { shallow, mount } from 'enzyme'; import useFakeDom from 'test/helpers/use-fake-dom'; import { TransactionIdFormComponent } from '..'; -describe( 'TransactionIdForm', () => { - it( 'should render as expected', () => { - const wrapper = shallow( ); - - expect( wrapper ).to.have.state( 'isSubmitting' ).to.be.false; - expect( wrapper.find( '.transaction-id-form__transaction-id-input' ).prop( 'disabled' ) ).to.not.be.ok; - expect( wrapper.find( '.transaction-id-form__continue-button' ).prop( 'disabled' ) ).to.be.ok; - expect( wrapper.find( '.transaction-id-form__skip-button' ).prop( 'disabled' ) ).to.not.be.ok; - } ); - - context( 'events', () => { - useFakeDom(); - - it( 'continue button should be disabled if transaction id is blank', function() { - const wrapper = mount( ); - - wrapper.find( '.transaction-id-form__transaction-id-input' ).node.value = ''; - wrapper.find( '.transaction-id-form__transaction-id-input' ).simulate( 'change' ); - expect( wrapper.find( '.transaction-id-form__transaction-id-input' ).prop( 'disabled' ) ).to.not.be.ok; - expect( wrapper.find( '.transaction-id-form__continue-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - - it( 'should be disabled when continue button clicked', function() { - const wrapper = mount( ); - - wrapper.find( '.transaction-id-form__transaction-id-input' ).node.value = 'test'; - wrapper.find( '.transaction-id-form__transaction-id-input' ).simulate( 'change' ); - wrapper.find( '.transaction-id-form__continue-button' ).simulate( 'click' ); - - expect( wrapper ).to.have.state( 'isSubmitting' ).to.be.true; - expect( wrapper.find( '.transaction-id-form__transaction-id-input' ).prop( 'disabled' ) ).to.be.ok; - expect( wrapper.find( '.transaction-id-form__continue-button' ).prop( 'disabled' ) ).to.be.ok; - } ); - } ); -} ); +describe('TransactionIdForm', () => { + it('should render as expected', () => { + const wrapper = shallow(); + + expect(wrapper).to.have.state('isSubmitting').to.be.false; + expect( + wrapper.find('.transaction-id-form__transaction-id-input').prop('disabled') + ).to.not.be.ok; + expect(wrapper.find('.transaction-id-form__continue-button').prop('disabled')).to.be.ok; + expect(wrapper.find('.transaction-id-form__skip-button').prop('disabled')).to.not.be.ok; + }); + + context('events', () => { + useFakeDom(); + + it('continue button should be disabled if transaction id is blank', function() { + const wrapper = mount(); + + wrapper.find('.transaction-id-form__transaction-id-input').node.value = ''; + wrapper.find('.transaction-id-form__transaction-id-input').simulate('change'); + expect( + wrapper.find('.transaction-id-form__transaction-id-input').prop('disabled') + ).to.not.be.ok; + expect(wrapper.find('.transaction-id-form__continue-button').prop('disabled')).to.be.ok; + }); + + it('should be disabled when continue button clicked', function() { + const wrapper = mount(); + + wrapper.find('.transaction-id-form__transaction-id-input').node.value = 'test'; + wrapper.find('.transaction-id-form__transaction-id-input').simulate('change'); + wrapper.find('.transaction-id-form__continue-button').simulate('click'); + + expect(wrapper).to.have.state('isSubmitting').to.be.true; + expect( + wrapper.find('.transaction-id-form__transaction-id-input').prop('disabled') + ).to.be.ok; + expect(wrapper.find('.transaction-id-form__continue-button').prop('disabled')).to.be.ok; + }); + }); +}); diff --git a/client/auth/auth-code-button.jsx b/client/auth/auth-code-button.jsx index 0d0e2c8ef9640..59e142307ad5c 100644 --- a/client/auth/auth-code-button.jsx +++ b/client/auth/auth-code-button.jsx @@ -10,58 +10,58 @@ import { requestCode, resetCode } from 'lib/auth-code-request-store/actions'; import { default as Store, requestState } from 'lib/auth-code-request-store'; import Notice from 'components/notice'; -export default React.createClass( { +export default React.createClass({ + componentDidMount: function() { + Store.on('change', this.refreshData); + }, - componentDidMount: function() { - Store.on( 'change', this.refreshData ); - }, + componentWillUnmount: function() { + Store.off('change', this.refreshData); + }, - componentWillUnmount: function() { - Store.off( 'change', this.refreshData ); - }, + refreshData: function() { + this.setState(Store.get()); + }, - refreshData: function() { - this.setState( Store.get() ); - }, + getInitialState: function() { + return Store.get(); + }, - getInitialState: function() { - return Store.get(); - }, + requestSMSCode: function(e) { + e.preventDefault(); + requestCode(this.props.username, this.props.password); + }, - requestSMSCode: function( e ) { - e.preventDefault(); - requestCode( this.props.username, this.props.password ); - }, + render: function() { + const { status, errorLevel, errorMessage } = this.state; - render: function() { - const { status, errorLevel, errorMessage } = this.state; + var noticeStatus = 'is-info'; + var showDismiss = false; + var message = ( + + {this.translate('Send code via text message.')} + + ); - var noticeStatus = 'is-info'; - var showDismiss = false; - var message = ( - { this.translate( 'Send code via text message.' ) } - ); + if (status === requestState.REQUESTING) { + message = this.translate('Requesting code.'); + } - if ( status === requestState.REQUESTING ) { - message = this.translate( 'Requesting code.' ); - } + if (status === requestState.COMPLETE) { + noticeStatus = 'is-success'; + message = this.translate('Code sent.'); + } - if ( status === requestState.COMPLETE ) { - noticeStatus = 'is-success'; - message = this.translate( 'Code sent.' ); - } + if (errorLevel !== false) { + noticeStatus = errorLevel; + message = errorMessage; + showDismiss = true; + } - if ( errorLevel !== false ) { - noticeStatus = errorLevel; - message = errorMessage; - showDismiss = true; - } - - return ( - - { message } - - ); - } - -} ) + return ( + + {message} + + ); + }, +}); diff --git a/client/auth/connect.jsx b/client/auth/connect.jsx index 8c6f0ae53d058..3f38f88774ad7 100644 --- a/client/auth/connect.jsx +++ b/client/auth/connect.jsx @@ -14,39 +14,54 @@ import Notice from 'components/notice'; import NoticeAction from 'components/notice/notice-action'; import WordPressLogo from 'components/wordpress-logo'; -const Connect = React.createClass( { +const Connect = React.createClass({ + getCreateAccountUrl() { + return config.isEnabled('devdocs') + ? 'https://wordpress.com/start/developer' + : 'https://wordpress.com/start'; + }, - getCreateAccountUrl() { - return config.isEnabled( 'devdocs' ) ? 'https://wordpress.com/start/developer' : 'https://wordpress.com/start'; - }, - - render() { - return ( -
- - { ! config( 'oauth_client_id' ) - ? - { this.translate( 'Go to Developer Resources' ) } - - :
-

- { this.translate( 'Welcome to Calypso. Authorize the application with your WordPress.com credentials to get started.' ) } -

- -
- } - - - - -
- ); - } -} ); + render() { + return ( +
+ + {!config('oauth_client_id') + ? + + {this.translate('Go to Developer Resources')} + + + :
+

+ {this.translate( + 'Welcome to Calypso. Authorize the application with your WordPress.com credentials to get started.' + )} +

+ +
} + + + + +
+ ); + }, +}); export default Connect; diff --git a/client/auth/controller.js b/client/auth/controller.js index 7ebb1b3c96224..85c55fa45ee48 100644 --- a/client/auth/controller.js +++ b/client/auth/controller.js @@ -21,93 +21,93 @@ import Main from 'components/main'; import PulsingDot from 'components/pulsing-dot'; module.exports = { + // Login screen used by the desktop application + login: function() { + if (OAuthToken.getToken()) { + page('/'); + } else { + ReactDom.render( + React.createElement(LoginComponent, {}), + document.getElementById('primary') + ); + } + }, - // Login screen used by the desktop application - login: function() { - if ( OAuthToken.getToken() ) { - page( '/' ); - } else { - ReactDom.render( - React.createElement( LoginComponent, {} ), - document.getElementById( 'primary' ) - ); - } - }, + checkToken: function(context, next) { + const loggedOutRoutes = ['/login', '/oauth', '/start', '/authorize', '/api/oauth/token'], + isValidSection = loggedOutRoutes.some(route => startsWith(context.path, route)); - checkToken: function( context, next ) { - const loggedOutRoutes = [ '/login', '/oauth', '/start', '/authorize', '/api/oauth/token' ], - isValidSection = loggedOutRoutes.some( route => startsWith( context.path, route ) ); + // Check we have an OAuth token, otherwise redirect to auth/login page + if (OAuthToken.getToken() === false && !isValidSection) { + if (config('env_id') === 'desktop') { + return page('/login'); + } - // Check we have an OAuth token, otherwise redirect to auth/login page - if ( OAuthToken.getToken() === false && ! isValidSection ) { - if ( config( 'env_id' ) === 'desktop' ) { - return page( '/login' ); - } + return page('/authorize'); + } - return page( '/authorize' ); - } + next(); + }, - next(); - }, + // This controller renders the API authentication screen + // for granting the app access to the user data using oauth + authorize: function() { + let authUrl; - // This controller renders the API authentication screen - // for granting the app access to the user data using oauth - authorize: function() { - let authUrl; + if (config('oauth_client_id')) { + const oauthSettings = { + response_type: 'token', + client_id: config('oauth_client_id'), + client_secret: 'n/a', + url: { + redirect: 'http://calypso.localhost:3000/api/oauth/token', + }, + }; - if ( config( 'oauth_client_id' ) ) { - const oauthSettings = { - response_type: 'token', - client_id: config( 'oauth_client_id' ), - client_secret: 'n/a', - url: { - redirect: 'http://calypso.localhost:3000/api/oauth/token' - } - }; + const wpoauth = WPOAuth(oauthSettings); + authUrl = wpoauth.urlToConnect({ scope: 'global', blog_id: 0 }); + } - const wpoauth = WPOAuth( oauthSettings ); - authUrl = wpoauth.urlToConnect( { scope: 'global', blog_id: 0 } ); - } + ReactDom.render( + React.createElement(ConnectComponent, { + authUrl: authUrl, + }), + document.getElementById('primary') + ); + }, - ReactDom.render( - React.createElement( ConnectComponent, { - authUrl: authUrl - } ), - document.getElementById( 'primary' ) - ); - }, + // Retrieve token from local storage + getToken: function(context) { + if (context.hash && context.hash.access_token) { + store.set('wpcom_token', context.hash.access_token); + wpcom.loadToken(context.hash.access_token); + } - // Retrieve token from local storage - getToken: function( context ) { - if ( context.hash && context.hash.access_token ) { - store.set( 'wpcom_token', context.hash.access_token ); - wpcom.loadToken( context.hash.access_token ); - } + if (context.hash && context.hash.expires_in) { + store.set('wpcom_token_expires_in', context.hash.expires_in); + } - if ( context.hash && context.hash.expires_in ) { - store.set( 'wpcom_token_expires_in', context.hash.expires_in ); - } + // Extract this into a component... + ReactDom.render( +
+

+ Loading user... +

+ +
, + document.getElementById('primary') + ); - // Extract this into a component... - ReactDom.render( ( -
-

- Loading user... -

- -
- ), document.getElementById( 'primary' ) ); - - // Fetch user and redirect to /sites on success. - const user = userFactory(); - user.fetching = false; - user.fetch(); - user.on( 'change', function() { - if ( config.isEnabled( 'devdocs' ) ) { - window.location = '/devdocs/welcome'; - } else { - window.location = '/'; - } - } ); - } + // Fetch user and redirect to /sites on success. + const user = userFactory(); + user.fetching = false; + user.fetch(); + user.on('change', function() { + if (config.isEnabled('devdocs')) { + window.location = '/devdocs/welcome'; + } else { + window.location = '/'; + } + }); + }, }; diff --git a/client/auth/index.js b/client/auth/index.js index a0e02cf18cdec..6c465f7054083 100644 --- a/client/auth/index.js +++ b/client/auth/index.js @@ -10,9 +10,9 @@ import config from 'config'; import controller from './controller'; module.exports = function() { - if ( config.isEnabled( 'oauth' ) ) { - page( '/login', controller.login ); - page( '/authorize', controller.authorize ); - page( '/api/oauth/token', controller.getToken ); - } + if (config.isEnabled('oauth')) { + page('/login', controller.login); + page('/authorize', controller.authorize); + page('/api/oauth/token', controller.getToken); + } }; diff --git a/client/auth/login.jsx b/client/auth/login.jsx index 9c8d75af770ab..24cc2f6932d1d 100644 --- a/client/auth/login.jsx +++ b/client/auth/login.jsx @@ -23,166 +23,216 @@ import eventRecorder from 'me/event-recorder'; import WordPressLogo from 'components/wordpress-logo'; import AuthCodeButton from './auth-code-button'; -const LostPassword = React.createClass( { - render: function() { - return ( -

- - { this.translate( 'Lost your password?' ) } - -

- ); - } -} ); - -const SelfHostedInstructions = React.createClass( { - - render: function() { - return ( -
- - -

{ this.translate( 'Add self-hosted site' ) }

-

{ this.translate( 'By default when you sign into the WordPress.com app, you can edit blogs and sites hosted at WordPress.com' ) }

-

{ this.translate( 'If you\'d like to edit your self-hosted WordPress blog or site, you can do that by following these instructions:' ) }

- -
    -
  1. { this.translate( 'Install the Jetpack plugin.' ) }
    { this.translate( 'Please follow these instructions to install Jetpack' ) }.
  2. -
  3. { this.translate( 'Connect Jetpack to WordPress.com.' ) }
  4. -
  5. { this.translate( 'Now you can sign in to the app using the WordPress.com account Jetpack is connected to, and you can find your self-hosted site under the "My Sites" section.' ) }
  6. -
-
- ); - } -} ); - -module.exports = React.createClass( { - displayName: 'Auth', - - mixins: [ LinkedStateMixin, eventRecorder ], - - componentDidMount: function() { - AuthStore.on( 'change', this.refreshData ); - }, - - componentWillUnmount: function() { - AuthStore.off( 'change', this.refreshData ); - }, - - refreshData: function() { - this.setState( AuthStore.get() ); - }, - - componentDidUpdate() { - if ( this.state.requires2fa && this.state.inProgress === false ) { - ReactDom.findDOMNode( this.refs.auth_code ).focus(); - } - }, - - getInitialState: function() { - return Object.assign( { - login: '', - password: '', - auth_code: '' - }, AuthStore.get() ); - }, - - submitForm: function( event ) { - event.preventDefault(); - event.stopPropagation(); - - AuthActions.login( this.state.login, this.state.password, this.state.auth_code ); - }, - - hasLoginDetails: function() { - if ( this.state.login === '' || this.state.password === '' ) { - return false; - } - - return true; - }, - - canSubmitForm: function() { - // No submission until the ajax has finished - if ( this.state.inProgress ) { - return false; - } - - // If we have 2fa set then don't allow submission until a code is entered - if ( this.state.requires2fa ) { - return parseInt( this.state.auth_code, 10 ) > 0; - } - - // Don't allow submission until username+password is entered - return this.hasLoginDetails(); - }, - - toggleSelfHostedInstructions: function () { - var isShowing = !this.state.showInstructions; - this.setState( { showInstructions: isShowing } ); - }, - - render: function() { - const { requires2fa, inProgress, errorMessage, errorLevel, showInstructions } = this.state; - - return ( -
- -
- -
- - -
-
- - -
- { requires2fa && - - - - } -
- - - { requires2fa ? this.translate( 'Verify' ) : this.translate( 'Sign in' ) } - - - { ! requires2fa && } - { errorMessage && } - { requires2fa && } - - - - - - { showInstructions && } -
- ); - } -} ); +const LostPassword = React.createClass({ + render: function() { + return ( +

+ + {this.translate('Lost your password?')} + +

+ ); + }, +}); + +const SelfHostedInstructions = React.createClass({ + render: function() { + return ( +
+ + + + +

{this.translate('Add self-hosted site')}

+

+ {this.translate( + 'By default when you sign into the WordPress.com app, you can edit blogs and sites hosted at WordPress.com' + )} +

+

+ {this.translate( + "If you'd like to edit your self-hosted WordPress blog or site, you can do that by following these instructions:" + )} +

+ +
    +
  1. + {this.translate('Install the Jetpack plugin.')} +
    + + {this.translate('Please follow these instructions to install Jetpack')} + + . +
  2. +
  3. {this.translate('Connect Jetpack to WordPress.com.')}
  4. +
  5. + {this.translate( + 'Now you can sign in to the app using the WordPress.com account Jetpack is connected to, and you can find your self-hosted site under the "My Sites" section.' + )} +
  6. +
+
+ ); + }, +}); + +module.exports = React.createClass({ + displayName: 'Auth', + + mixins: [LinkedStateMixin, eventRecorder], + + componentDidMount: function() { + AuthStore.on('change', this.refreshData); + }, + + componentWillUnmount: function() { + AuthStore.off('change', this.refreshData); + }, + + refreshData: function() { + this.setState(AuthStore.get()); + }, + + componentDidUpdate() { + if (this.state.requires2fa && this.state.inProgress === false) { + ReactDom.findDOMNode(this.refs.auth_code).focus(); + } + }, + + getInitialState: function() { + return Object.assign( + { + login: '', + password: '', + auth_code: '', + }, + AuthStore.get() + ); + }, + + submitForm: function(event) { + event.preventDefault(); + event.stopPropagation(); + + AuthActions.login(this.state.login, this.state.password, this.state.auth_code); + }, + + hasLoginDetails: function() { + if (this.state.login === '' || this.state.password === '') { + return false; + } + + return true; + }, + + canSubmitForm: function() { + // No submission until the ajax has finished + if (this.state.inProgress) { + return false; + } + + // If we have 2fa set then don't allow submission until a code is entered + if (this.state.requires2fa) { + return parseInt(this.state.auth_code, 10) > 0; + } + + // Don't allow submission until username+password is entered + return this.hasLoginDetails(); + }, + + toggleSelfHostedInstructions: function() { + var isShowing = !this.state.showInstructions; + this.setState({ showInstructions: isShowing }); + }, + + render: function() { + const { requires2fa, inProgress, errorMessage, errorLevel, showInstructions } = this.state; + + return ( +
+ +
+ +
+ + +
+
+ + +
+ {requires2fa && + + + } +
+ + + {requires2fa ? this.translate('Verify') : this.translate('Sign in')} + + + {!requires2fa && } + {errorMessage && + } + {requires2fa && + } + + + + + + {showInstructions && + } +
+ ); + }, +}); diff --git a/client/auth/test/login.jsx b/client/auth/test/login.jsx index 21fde5c49dcc6..542c94829311f 100644 --- a/client/auth/test/login.jsx +++ b/client/auth/test/login.jsx @@ -11,68 +11,68 @@ import { stub } from 'sinon'; import useFakeDom from 'test/helpers/use-fake-dom'; import useMockery from 'test/helpers/use-mockery'; -describe( 'LoginTest', function() { - let Login, loginStub, page, React, ReactDom, ReactClass, TestUtils; +describe('LoginTest', function() { + let Login, loginStub, page, React, ReactDom, ReactClass, TestUtils; - useFakeDom.withContainer(); - useMockery( ( mockery ) => { - loginStub = stub(); - mockery.registerMock( 'lib/oauth-store/actions', { - login: loginStub - } ); - mockery.registerMock( 'lib/analytics', { ga: { recordEvent: noop } } ); - } ); + useFakeDom.withContainer(); + useMockery(mockery => { + loginStub = stub(); + mockery.registerMock('lib/oauth-store/actions', { + login: loginStub, + }); + mockery.registerMock('lib/analytics', { ga: { recordEvent: noop } }); + }); - before( () => { - React = require( 'react' ); - ReactDom = require( 'react-dom' ); - ReactClass = require( 'react/lib/ReactClass' ); - TestUtils = require( 'react-addons-test-utils' ); - ReactClass.injection.injectMixin( { translate: identity } ); - Login = require( '../login.jsx' ); - page = ReactDom.render( , useFakeDom.getContainer() ); - } ); + before(() => { + React = require('react'); + ReactDom = require('react-dom'); + ReactClass = require('react/lib/ReactClass'); + TestUtils = require('react-addons-test-utils'); + ReactClass.injection.injectMixin({ translate: identity }); + Login = require('../login.jsx'); + page = ReactDom.render(, useFakeDom.getContainer()); + }); - it( 'OTP is not present on first render', function( done ) { - page.setState( { requires2fa: false }, function() { - expect( page.refs.auth_code ).to.be.undefined; - done(); - } ); - } ); + it('OTP is not present on first render', function(done) { + page.setState({ requires2fa: false }, function() { + expect(page.refs.auth_code).to.be.undefined; + done(); + }); + }); - it( 'cannot submit until login details entered', function( done ) { - const submit = TestUtils.findRenderedDOMComponentWithTag( page, 'button' ); + it('cannot submit until login details entered', function(done) { + const submit = TestUtils.findRenderedDOMComponentWithTag(page, 'button'); - page.setState( { login: 'test', password: 'test', inProgress: false }, function() { - expect( submit.disabled ).to.be.false; - done(); - } ); - } ); + page.setState({ login: 'test', password: 'test', inProgress: false }, function() { + expect(submit.disabled).to.be.false; + done(); + }); + }); - it( 'shows OTP box with valid login', function( done ) { - page.setState( { login: 'test', password: 'test', requires2fa: true }, function() { - expect( page.refs.auth_code ).to.not.be.undefined; - done(); - } ); - } ); + it('shows OTP box with valid login', function(done) { + page.setState({ login: 'test', password: 'test', requires2fa: true }, function() { + expect(page.refs.auth_code).to.not.be.undefined; + done(); + }); + }); - it( 'prevents change of login when asking for OTP', function( done ) { - page.setState( { login: 'test', password: 'test', requires2fa: true }, function() { - expect( page.refs.login.props.disabled ).to.be.true; - expect( page.refs.password.props.disabled ).to.be.true; - done(); - } ); - } ); + it('prevents change of login when asking for OTP', function(done) { + page.setState({ login: 'test', password: 'test', requires2fa: true }, function() { + expect(page.refs.login.props.disabled).to.be.true; + expect(page.refs.password.props.disabled).to.be.true; + done(); + }); + }); - it( 'submits login form', function( done ) { - const submit = TestUtils.findRenderedDOMComponentWithTag( page, 'form' ); + it('submits login form', function(done) { + const submit = TestUtils.findRenderedDOMComponentWithTag(page, 'form'); - page.setState( { login: 'user', password: 'pass', auth_code: 'otp' }, function() { - TestUtils.Simulate.submit( submit ); + page.setState({ login: 'user', password: 'pass', auth_code: 'otp' }, function() { + TestUtils.Simulate.submit(submit); - expect( loginStub ).to.have.been.calledOnce; - expect( loginStub.calledWith( 'user', 'pass', 'otp' ) ).to.be.true; - done(); - } ); - } ); -} ); + expect(loginStub).to.have.been.calledOnce; + expect(loginStub.calledWith('user', 'pass', 'otp')).to.be.true; + done(); + }); + }); +}); diff --git a/client/blocks/app-promo/index.jsx b/client/blocks/app-promo/index.jsx index c4da4a12975e9..4650eba2a4069 100644 --- a/client/blocks/app-promo/index.jsx +++ b/client/blocks/app-promo/index.jsx @@ -14,125 +14,124 @@ import { localize } from 'i18n-calypso'; import { recordTracksEvent } from 'state/analytics/actions'; const getRandomPromo = () => { - const promoOptions = [ - { - promoCode: 'a0001', - message: 'WordPress.com your way — desktop app now available for Mac, Windows, and Linux.', - type: 'desktop', - }, - { - promoCode: 'a0002', - message: 'Get WordPress.com app for your desktop.', - type: 'desktop' - }, - { - promoCode: 'a0003', - message: 'WordPress.com app now available for desktop.', - type: 'desktop' - }, - { - promoCode: 'a0005', - message: 'WordPress.com at your fingertips — download app for desktop.', - type: 'desktop' - }, - { - promoCode: 'a0006', - message: 'WordPress.com in the palm of your hands — download app for mobile.', - type: 'mobile' - } - ]; - - return sample( promoOptions ); + const promoOptions = [ + { + promoCode: 'a0001', + message: 'WordPress.com your way — desktop app now available for Mac, Windows, and Linux.', + type: 'desktop', + }, + { + promoCode: 'a0002', + message: 'Get WordPress.com app for your desktop.', + type: 'desktop', + }, + { + promoCode: 'a0003', + message: 'WordPress.com app now available for desktop.', + type: 'desktop', + }, + { + promoCode: 'a0005', + message: 'WordPress.com at your fingertips — download app for desktop.', + type: 'desktop', + }, + { + promoCode: 'a0006', + message: 'WordPress.com in the palm of your hands — download app for mobile.', + type: 'mobile', + }, + ]; + + return sample(promoOptions); }; -export const getPromoLink = ( location, promoDetails ) => { - const { type, promoCode } = promoDetails; +export const getPromoLink = (location, promoDetails) => { + const { type, promoCode } = promoDetails; - return `https://apps.wordpress.com/${ type }/?ref=promo_${ location }_${ promoCode }`; + return `https://apps.wordpress.com/${type}/?ref=promo_${location}_${promoCode}`; }; -export const AppPromo = React.createClass( { - - displayName: 'AppPromo', - - propTypes: { - location: React.PropTypes.string.isRequired - }, - - getInitialState: function() { - const promoItem = this.props.promoItem || getRandomPromo(); - return { - promoItem, - showPromo: true - }; - }, - - componentDidMount: function() { - this.props.recordTracksEvent( 'calypso_desktop_promo_view', { - promo_location: this.props.location, - promo_code: this.state.promoItem.promoCode, - } ); - }, - - recordClickEvent: function() { - this.props.recordTracksEvent( 'calypso_desktop_promo_click', { - promo_location: this.props.location, - promo_code: this.state.promoItem.promoCode - } ); - }, - - dismiss: function() { - this.setState( { showPromo: false } ); - this.props.saveDismissal(); - this.props.recordTracksEvent( 'calypso_desktop_promo_dismiss', { - promo_location: this.props.location, - promo_code: this.state.promoItem.promoCode, - } ); - }, - - render: function() { - if ( ! this.state.showPromo ) { - return null; - } - - const { location, translate } = this.props; - const { promoItem } = this.state; - - return ( -
- - - - { translate( 'Dismiss' ) } - - - - WordPress Desktop Icon - { promoItem.message } - -
- ); - }, -} ); +export const AppPromo = React.createClass({ + displayName: 'AppPromo', + + propTypes: { + location: React.PropTypes.string.isRequired, + }, + + getInitialState: function() { + const promoItem = this.props.promoItem || getRandomPromo(); + return { + promoItem, + showPromo: true, + }; + }, + + componentDidMount: function() { + this.props.recordTracksEvent('calypso_desktop_promo_view', { + promo_location: this.props.location, + promo_code: this.state.promoItem.promoCode, + }); + }, + + recordClickEvent: function() { + this.props.recordTracksEvent('calypso_desktop_promo_click', { + promo_location: this.props.location, + promo_code: this.state.promoItem.promoCode, + }); + }, + + dismiss: function() { + this.setState({ showPromo: false }); + this.props.saveDismissal(); + this.props.recordTracksEvent('calypso_desktop_promo_dismiss', { + promo_location: this.props.location, + promo_code: this.state.promoItem.promoCode, + }); + }, + + render: function() { + if (!this.state.showPromo) { + return null; + } + + const { location, translate } = this.props; + const { promoItem } = this.state; + + return ( +
+ + + + {translate('Dismiss')} + + + + WordPress Desktop Icon + {promoItem.message} + +
+ ); + }, +}); AppPromo.defaultProps = { - translate: identity, - recordTracksEvent: noop, - saveDismissal: () => store.set( 'desktop_promo_disabled', true ), - getPromoLink + translate: identity, + recordTracksEvent: noop, + saveDismissal: () => store.set('desktop_promo_disabled', true), + getPromoLink, }; -export default connect( null, { recordTracksEvent } )( localize( AppPromo ) ) ; +export default connect(null, { recordTracksEvent })(localize(AppPromo)); diff --git a/client/blocks/app-promo/test/index.jsx b/client/blocks/app-promo/test/index.jsx index 3078b15eb670f..0cc5778bfb1ff 100644 --- a/client/blocks/app-promo/test/index.jsx +++ b/client/blocks/app-promo/test/index.jsx @@ -10,75 +10,75 @@ import { shallow } from 'enzyme'; */ import useFakeDom from 'test/helpers/use-fake-dom'; -describe( 'AppPromo', ( ) => { - useFakeDom(); +describe('AppPromo', () => { + useFakeDom(); - const appPromoDetails = { - promoCode: 'a0001', - message: 'WordPress.com your way — desktop app now available for Mac, Windows, and Linux.' - }; - const appPromoLink = 'http://www.wordpress.com'; + const appPromoDetails = { + promoCode: 'a0001', + message: 'WordPress.com your way — desktop app now available for Mac, Windows, and Linux.', + }; + const appPromoLink = 'http://www.wordpress.com'; - let AppPromo; - let AppPromoComponent; - let getPromoLink; - const defaultPropsToRender = { - location: 'reader', - promoItem: appPromoDetails, - getPromoLink: () => appPromoLink - }; - // The reason we don't import this higher up is this component can't be - // imported until the fake DOM is setup. - before( ( ) => { - AppPromo = require( '..' ).AppPromo; - getPromoLink = require( '..' ).getPromoLink; - AppPromoComponent = ( ); - } ); + let AppPromo; + let AppPromoComponent; + let getPromoLink; + const defaultPropsToRender = { + location: 'reader', + promoItem: appPromoDetails, + getPromoLink: () => appPromoLink, + }; + // The reason we don't import this higher up is this component can't be + // imported until the fake DOM is setup. + before(() => { + AppPromo = require('..').AppPromo; + getPromoLink = require('..').getPromoLink; + AppPromoComponent = ; + }); - context( 'readering', ( ) => { - it( 'should render the primary components', ( ) => { - const wrapper = shallow( AppPromoComponent ); + context('readering', () => { + it('should render the primary components', () => { + const wrapper = shallow(AppPromoComponent); - expect( wrapper ).to.have.descendants( '.app-promo' ); - expect( wrapper ).to.have.descendants( '.app-promo__dismiss' ); - expect( wrapper ).to.have.descendants( '.app-promo__screen-reader-text' ); - expect( wrapper ).to.have.descendants( '.app-promo__icon' ); - } ); + expect(wrapper).to.have.descendants('.app-promo'); + expect(wrapper).to.have.descendants('.app-promo__dismiss'); + expect(wrapper).to.have.descendants('.app-promo__screen-reader-text'); + expect(wrapper).to.have.descendants('.app-promo__icon'); + }); - it( 'should render the promo text', ( ) => { - const wrapper = shallow( AppPromoComponent ); + it('should render the promo text', () => { + const wrapper = shallow(AppPromoComponent); - expect( wrapper.text() ).to.contain( appPromoDetails.message ); - } ); + expect(wrapper.text()).to.contain(appPromoDetails.message); + }); - it( 'should render the promo link', ( ) => { - const wrapper = shallow( AppPromoComponent ); + it('should render the promo link', () => { + const wrapper = shallow(AppPromoComponent); - const promoLink = wrapper.find( '.app-promo__link' ); - expect( promoLink ).to.have.lengthOf( 1 ); - expect( promoLink ).to.have.prop( 'href' ).equal( appPromoLink ); - } ); - } ); + const promoLink = wrapper.find('.app-promo__link'); + expect(promoLink).to.have.lengthOf(1); + expect(promoLink).to.have.prop('href').equal(appPromoLink); + }); + }); - context( 'getPromoLink', ( ) => { - const mobilePromo = { - promoCode: 'a0006', - message: 'WordPress.com in the palm of your hands — download app for mobile.', - type: 'mobile', - } + context('getPromoLink', () => { + const mobilePromo = { + promoCode: 'a0006', + message: 'WordPress.com in the palm of your hands — download app for mobile.', + type: 'mobile', + }; - const desktopPromo = { - promoCode: 'a0005', - message: 'WordPress.com at your fingertips — download app for desktop.', - type: 'desktop' - } + const desktopPromo = { + promoCode: 'a0005', + message: 'WordPress.com at your fingertips — download app for desktop.', + type: 'desktop', + }; - it('should render a mobile link when the mobile promo code is passed in', ( ) => { - expect( getPromoLink( 'reader', mobilePromo ) ).to.include( 'mobile' ); - }); + it('should render a mobile link when the mobile promo code is passed in', () => { + expect(getPromoLink('reader', mobilePromo)).to.include('mobile'); + }); - it('should render a desktop link when the desktop promo code is passed in', ( ) => { - expect( getPromoLink( 'reader', desktopPromo ) ).to.include( 'desktop' ); - }); - }); -} ); + it('should render a desktop link when the desktop promo code is passed in', () => { + expect(getPromoLink('reader', desktopPromo)).to.include('desktop'); + }); + }); +}); diff --git a/client/blocks/author-compact-profile/docs/example.jsx b/client/blocks/author-compact-profile/docs/example.jsx index 2f123ce7cbf91..377813c266bf1 100644 --- a/client/blocks/author-compact-profile/docs/example.jsx +++ b/client/blocks/author-compact-profile/docs/example.jsx @@ -9,27 +9,27 @@ import React from 'react'; import AuthorCompactProfile from 'blocks/author-compact-profile'; import Card from 'components/card'; -export default React.createClass( { +export default React.createClass({ + displayName: 'AuthorCompactProfile', - displayName: 'AuthorCompactProfile', + render() { + const author = { + avatar_URL: 'https://0.gravatar.com/avatar/cf55adb1a5146c0a11a808bce7842f7b?s=96&d=identicon', + name: 'Bob The Tester', + URL: 'http://wpcalypso.wordpress.com', + }; - render() { - const author = { - avatar_URL: 'https://0.gravatar.com/avatar/cf55adb1a5146c0a11a808bce7842f7b?s=96&d=identicon', - name: 'Bob The Tester', - URL: 'http://wpcalypso.wordpress.com' - }; - - return ( - - - - ); - } -} ); + return ( + + + + ); + }, +}); diff --git a/client/blocks/author-compact-profile/index.jsx b/client/blocks/author-compact-profile/index.jsx index 7de589f1e9a58..4a5978fcdb9be 100644 --- a/client/blocks/author-compact-profile/index.jsx +++ b/client/blocks/author-compact-profile/index.jsx @@ -17,72 +17,92 @@ import { getStreamUrl } from 'reader/route'; import { areEqualIgnoringWhitespaceAndCase } from 'lib/string'; import AuthorCompactProfilePlaceholder from './placeholder'; -const AuthorCompactProfile = React.createClass( { - propTypes: { - author: React.PropTypes.object, - siteName: React.PropTypes.string, - siteUrl: React.PropTypes.string, - feedUrl: React.PropTypes.string, - followCount: React.PropTypes.number, - feedId: React.PropTypes.number, - siteId: React.PropTypes.number, - siteIcon: React.PropTypes.string, - feedIcon: React.PropTypes.string, - post: React.PropTypes.object, - }, +const AuthorCompactProfile = React.createClass({ + propTypes: { + author: React.PropTypes.object, + siteName: React.PropTypes.string, + siteUrl: React.PropTypes.string, + feedUrl: React.PropTypes.string, + followCount: React.PropTypes.number, + feedId: React.PropTypes.number, + siteId: React.PropTypes.number, + siteIcon: React.PropTypes.string, + feedIcon: React.PropTypes.string, + post: React.PropTypes.object, + }, - render() { - const { author, siteIcon, feedIcon, siteName, siteUrl, feedUrl, followCount, feedId, siteId, post } = this.props; + render() { + const { + author, + siteIcon, + feedIcon, + siteName, + siteUrl, + feedUrl, + followCount, + feedId, + siteId, + post, + } = this.props; - if ( ! author ) { - return ; - } + if (!author) { + return ; + } - const hasAuthorName = has( author, 'name' ); - const hasMatchingAuthorAndSiteNames = hasAuthorName && areEqualIgnoringWhitespaceAndCase( siteName, author.name ); - const classes = classnames( { - 'author-compact-profile': true, - 'has-author-link': ! hasMatchingAuthorAndSiteNames, - 'has-author-icon': siteIcon || feedIcon || ( author && author.has_avatar ) - } ); - const streamUrl = getStreamUrl( feedId, siteId ); + const hasAuthorName = has(author, 'name'); + const hasMatchingAuthorAndSiteNames = hasAuthorName && + areEqualIgnoringWhitespaceAndCase(siteName, author.name); + const classes = classnames({ + 'author-compact-profile': true, + 'has-author-link': !hasMatchingAuthorAndSiteNames, + 'has-author-icon': siteIcon || feedIcon || (author && author.has_avatar), + }); + const streamUrl = getStreamUrl(feedId, siteId); - // If we have a feed URL, use that for the follow button in preference to the site URL - const followUrl = feedUrl || siteUrl; + // If we have a feed URL, use that for the follow button in preference to the site URL + const followUrl = feedUrl || siteUrl; - return ( -
- - - - { hasAuthorName && ! hasMatchingAuthorAndSiteNames && - { author.name } } - { siteName && - - { siteName } - } + return ( +
+ + + + {hasAuthorName && + !hasMatchingAuthorAndSiteNames && + + {author.name} + } + {siteName && + + {siteName} + } -
- { followCount - ?
- { this.props.translate( - '%(followCount)s follower', - '%(followCount)s followers', - { - count: followCount, - args: { - followCount: numberFormat( followCount ) - } - } - ) } -
: null } +
+ {followCount + ?
+ {this.props.translate( + '%(followCount)s follower', + '%(followCount)s followers', + { + count: followCount, + args: { + followCount: numberFormat(followCount), + }, + } + )} +
+ : null} - { followUrl && } -
-
- ); - } + {followUrl && } +
+
+ ); + }, +}); -} ); - -export default localize( AuthorCompactProfile ); +export default localize(AuthorCompactProfile); diff --git a/client/blocks/author-compact-profile/placeholder.jsx b/client/blocks/author-compact-profile/placeholder.jsx index 1e95bec126f0f..e84c582e768f1 100644 --- a/client/blocks/author-compact-profile/placeholder.jsx +++ b/client/blocks/author-compact-profile/placeholder.jsx @@ -9,21 +9,21 @@ import React from 'react'; import ReaderAvatar from 'blocks/reader-avatar'; const AuthorCompactProfilePlaceholder = () => { - return ( -
-
- -
-
- Site name -
-
-
- Number of followers -
-
-
- ); + return ( +
+
+ +
+
+ Site name +
+
+
+ Number of followers +
+
+
+ ); }; export default AuthorCompactProfilePlaceholder; diff --git a/client/blocks/author-selector/docs/example.jsx b/client/blocks/author-selector/docs/example.jsx index d872bf9b398bd..3c9a0ca2c97c2 100644 --- a/client/blocks/author-selector/docs/example.jsx +++ b/client/blocks/author-selector/docs/example.jsx @@ -11,31 +11,27 @@ import AuthorSelector from '../'; import Card from 'components/card'; import { getCurrentUser } from 'state/current-user/selectors'; -function AuthorSelectorExample( { primarySiteId, displayName } ) { - return ( - - - You are { displayName } - - - ); +function AuthorSelectorExample({ primarySiteId, displayName }) { + return ( + + + You are {displayName} + + + ); } -const ConnectedAuthorSelectorExample = connect( ( state ) => { - const user = getCurrentUser( state ); - if ( ! user ) { - return {}; - } +const ConnectedAuthorSelectorExample = connect(state => { + const user = getCurrentUser(state); + if (!user) { + return {}; + } - return { - primarySiteId: user.primary_blog, - displayName: user.display_name - }; -} )( AuthorSelectorExample ); + return { + primarySiteId: user.primary_blog, + displayName: user.display_name, + }; +})(AuthorSelectorExample); ConnectedAuthorSelectorExample.displayName = 'AuthorSelector'; diff --git a/client/blocks/author-selector/index.jsx b/client/blocks/author-selector/index.jsx index 97ceec099887a..aa36403630310 100644 --- a/client/blocks/author-selector/index.jsx +++ b/client/blocks/author-selector/index.jsx @@ -22,272 +22,280 @@ import { hasTouch } from 'lib/touch-detect'; /** * Module variables */ -const debug = debugModule( 'calypso:author-selector' ); +const debug = debugModule('calypso:author-selector'); let instance = 0; -const SwitcherShell = React.createClass( { - displayName: 'AuthorSwitcherShell', - propTypes: { - users: React.PropTypes.array, - fetchingUsers: React.PropTypes.bool, - numUsersFetched: React.PropTypes.number, - totalUsers: React.PropTypes.number, - usersCurrentOffset: React.PropTypes.number, - allowSingleUser: React.PropTypes.bool, - popoverPosition: React.PropTypes.string, - ignoreContext: React.PropTypes.shape( { getDOMNode: React.PropTypes.func } ) - }, - - getInitialState: function() { - return { - showAuthorMenu: false - }; - }, - - componentWillMount: function() { - this.instance = instance; - instance++; - }, - - componentWillReceiveProps: function( nextProps ) { - if ( ! nextProps.fetchOptions.siteId || nextProps.fetchOptions.siteId !== this.props.fetchOptions.siteId ) { - this.props.updateSearch( false ); - } - }, - - componentDidUpdate: function( prevProps, prevState ) { - if ( ! this.state.showAuthorMenu ) { - return; - } - - if ( ! prevState.showAuthorMenu && this.props.users.length > 10 && ! hasTouch() ) { - setTimeout( () => this.refs.authorSelectorSearch.focus(), 0 ); - } - }, - - render: function() { - const { users, fetchNameSpace } = this.props; - const infiniteListKey = fetchNameSpace + this.instance; - - if ( ! this._userCanSelectAuthor() ) { - return { this.props.children }; - } - - return ( - - - { this.props.children } - - - - { ( this.props.fetchOptions.search || users.length > 10 ) && - - } - { this.props.fetchInitialized && ! users.length && this.props.fetchOptions.search && ! this.props.fetchingUsers - ? this._noUsersFound() - : ( - - - ) - } - - - ); - }, - - _isLastPage: function() { - let usersLength = this.props.users.length; - if ( this.props.exclude ) { - usersLength += this.props.excludedUsers.length; - } - - return this.props.totalUsers <= usersLength; - }, - - _setListContext: function( infiniteListInstance ) { - this.setState( { - listContext: ReactDom.findDOMNode( infiniteListInstance ) - } ); - }, - - _userCanSelectAuthor: function() { - const { users } = this.props; - - if ( this.props.fetchOptions.search ) { - return true; - } - - // no user choice - if ( ! users || ! users.length || ( ! this.props.allowSingleUser && users.length === 1 ) ) { - return false; - } - - return true; - }, - - _toggleShowAuthor: function() { - this.setState( { - showAuthorMenu: ! this.state.showAuthorMenu - } ); - }, - - _onClose: function( event ) { - const toggleElement = ReactDom.findDOMNode( this.refs[ 'author-selector-toggle' ] ); - - if ( event && toggleElement.contains( event.target ) ) { - // let _toggleShowAuthor() handle this case - return; - } - this.setState( { - showAuthorMenu: false - } ); - this.props.updateSearch( false ); - }, - - _renderAuthor: function( author ) { - const authorGUID = this._getAuthorItemGUID( author ); - return ( - - - - ); - }, - - _noUsersFound: function() { - return ( -
- { this.translate( 'No matching users found.' ) } -
- ); - }, - - _selectAuthor: function( author ) { - debug( 'assign author:', author ); - if ( this.props.onSelect ) { - this.props.onSelect( author ); - } - this.setState( { - showAuthorMenu: false - } ); - this.props.updateSearch( false ); - }, - - _fetchNextPage: function() { - const fetchOptions = Object.assign( {}, this.props.fetchOptions, { offset: this.props.users.length } ); - debug( 'fetching next batch of authors' ); - UsersActions.fetchUsers( fetchOptions ); - }, - - _getAuthorItemGUID: function( author ) { - return 'author-item-' + author.ID; - }, - - _renderLoadingAuthors: function() { - return ( - - - - ); - }, - - _onSearch: function( searchTerm ) { - this.props.updateSearch( searchTerm ); - } -} ); - -module.exports = React.createClass( { - displayName: 'AuthorSelector', - propTypes: { - siteId: React.PropTypes.number.isRequired, - onSelect: React.PropTypes.func, - exclude: React.PropTypes.arrayOf( React.PropTypes.number ), - allowSingleUser: React.PropTypes.bool, - popoverPosition: React.PropTypes.string - }, - - getInitialState: function() { - return { - search: '' - }; - }, - - getDefaultProps: function() { - return { - showAuthorMenu: false, - onClose: function() {}, - allowSingleUser: false, - popoverPosition: 'bottom left' - }; - }, - - componentDidMount: function() { - debug( 'AuthorSelector mounted' ); - }, - - render: function() { - let searchString = this.state.search || ''; - searchString = trim( searchString ); - - const fetchOptions = { - siteId: this.props.siteId, - order: 'ASC', - order_by: 'display_name', - number: 50 - }; - - if ( searchString ) { - fetchOptions.number = 20; // make search a little faster - fetchOptions.search = searchString; - fetchOptions.search_columns = [ 'user_login', 'display_name' ]; - } - - Object.freeze( fetchOptions ); - return ( - - - - ); - }, - - _updateSearch: function( searchTerm ) { - searchTerm = searchTerm ? '*' + searchTerm + '*' : ''; - this.setState( { - search: searchTerm - } ); - } -} ); +const SwitcherShell = React.createClass({ + displayName: 'AuthorSwitcherShell', + propTypes: { + users: React.PropTypes.array, + fetchingUsers: React.PropTypes.bool, + numUsersFetched: React.PropTypes.number, + totalUsers: React.PropTypes.number, + usersCurrentOffset: React.PropTypes.number, + allowSingleUser: React.PropTypes.bool, + popoverPosition: React.PropTypes.string, + ignoreContext: React.PropTypes.shape({ getDOMNode: React.PropTypes.func }), + }, + + getInitialState: function() { + return { + showAuthorMenu: false, + }; + }, + + componentWillMount: function() { + this.instance = instance; + instance++; + }, + + componentWillReceiveProps: function(nextProps) { + if ( + !nextProps.fetchOptions.siteId || + nextProps.fetchOptions.siteId !== this.props.fetchOptions.siteId + ) { + this.props.updateSearch(false); + } + }, + + componentDidUpdate: function(prevProps, prevState) { + if (!this.state.showAuthorMenu) { + return; + } + + if (!prevState.showAuthorMenu && this.props.users.length > 10 && !hasTouch()) { + setTimeout(() => this.refs.authorSelectorSearch.focus(), 0); + } + }, + + render: function() { + const { users, fetchNameSpace } = this.props; + const infiniteListKey = fetchNameSpace + this.instance; + + if (!this._userCanSelectAuthor()) { + return {this.props.children}; + } + + return ( + + + {this.props.children} + + + + {(this.props.fetchOptions.search || users.length > 10) && + } + {this.props.fetchInitialized && + !users.length && + this.props.fetchOptions.search && + !this.props.fetchingUsers + ? this._noUsersFound() + : } + + + ); + }, + + _isLastPage: function() { + let usersLength = this.props.users.length; + if (this.props.exclude) { + usersLength += this.props.excludedUsers.length; + } + + return this.props.totalUsers <= usersLength; + }, + + _setListContext: function(infiniteListInstance) { + this.setState({ + listContext: ReactDom.findDOMNode(infiniteListInstance), + }); + }, + + _userCanSelectAuthor: function() { + const { users } = this.props; + + if (this.props.fetchOptions.search) { + return true; + } + + // no user choice + if (!users || !users.length || (!this.props.allowSingleUser && users.length === 1)) { + return false; + } + + return true; + }, + + _toggleShowAuthor: function() { + this.setState({ + showAuthorMenu: !this.state.showAuthorMenu, + }); + }, + + _onClose: function(event) { + const toggleElement = ReactDom.findDOMNode(this.refs['author-selector-toggle']); + + if (event && toggleElement.contains(event.target)) { + // let _toggleShowAuthor() handle this case + return; + } + this.setState({ + showAuthorMenu: false, + }); + this.props.updateSearch(false); + }, + + _renderAuthor: function(author) { + const authorGUID = this._getAuthorItemGUID(author); + return ( + + + + ); + }, + + _noUsersFound: function() { + return ( +
+ {this.translate('No matching users found.')} +
+ ); + }, + + _selectAuthor: function(author) { + debug('assign author:', author); + if (this.props.onSelect) { + this.props.onSelect(author); + } + this.setState({ + showAuthorMenu: false, + }); + this.props.updateSearch(false); + }, + + _fetchNextPage: function() { + const fetchOptions = Object.assign({}, this.props.fetchOptions, { + offset: this.props.users.length, + }); + debug('fetching next batch of authors'); + UsersActions.fetchUsers(fetchOptions); + }, + + _getAuthorItemGUID: function(author) { + return 'author-item-' + author.ID; + }, + + _renderLoadingAuthors: function() { + return ( + + + + ); + }, + + _onSearch: function(searchTerm) { + this.props.updateSearch(searchTerm); + }, +}); + +module.exports = React.createClass({ + displayName: 'AuthorSelector', + propTypes: { + siteId: React.PropTypes.number.isRequired, + onSelect: React.PropTypes.func, + exclude: React.PropTypes.arrayOf(React.PropTypes.number), + allowSingleUser: React.PropTypes.bool, + popoverPosition: React.PropTypes.string, + }, + + getInitialState: function() { + return { + search: '', + }; + }, + + getDefaultProps: function() { + return { + showAuthorMenu: false, + onClose: function() {}, + allowSingleUser: false, + popoverPosition: 'bottom left', + }; + }, + + componentDidMount: function() { + debug('AuthorSelector mounted'); + }, + + render: function() { + let searchString = this.state.search || ''; + searchString = trim(searchString); + + const fetchOptions = { + siteId: this.props.siteId, + order: 'ASC', + order_by: 'display_name', + number: 50, + }; + + if (searchString) { + fetchOptions.number = 20; // make search a little faster + fetchOptions.search = searchString; + fetchOptions.search_columns = ['user_login', 'display_name']; + } + + Object.freeze(fetchOptions); + return ( + + + + ); + }, + + _updateSearch: function(searchTerm) { + searchTerm = searchTerm ? '*' + searchTerm + '*' : ''; + this.setState({ + search: searchTerm, + }); + }, +}); diff --git a/client/blocks/comment-button/docs/example.jsx b/client/blocks/comment-button/docs/example.jsx index 5d64a0967e478..4516228207ede 100644 --- a/client/blocks/comment-button/docs/example.jsx +++ b/client/blocks/comment-button/docs/example.jsx @@ -9,19 +9,19 @@ import React from 'react'; import CommentButton from 'blocks/comment-button'; import Card from 'components/card'; -export default React.createClass( { - displayName: 'CommentButtonExample', +export default React.createClass({ + displayName: 'CommentButtonExample', - render() { - return ( -
- - - - - - -
- ); - } -} ); + render() { + return ( +
+ + + + + + +
+ ); + }, +}); diff --git a/client/blocks/comment-button/index.jsx b/client/blocks/comment-button/index.jsx index 3f3a079d7aac8..d12f632c22935 100644 --- a/client/blocks/comment-button/index.jsx +++ b/client/blocks/comment-button/index.jsx @@ -13,63 +13,62 @@ import Gridicon from 'gridicons'; import { getPostTotalCommentsCount } from 'state/comments/selectors'; class CommentButton extends Component { + static propTypes = { + onClick: React.PropTypes.func, + tagName: React.PropTypes.string, + commentCount: React.PropTypes.number, + showLabel: React.PropTypes.bool, + }; - static propTypes = { - onClick: React.PropTypes.func, - tagName: React.PropTypes.string, - commentCount: React.PropTypes.number, - showLabel: React.PropTypes.bool - }; + static defaultProps = { + onClick: noop, + tagName: 'li', + size: 24, + commentCount: 0, + showLabel: true, + }; - static defaultProps = { - onClick: noop, - tagName: 'li', - size: 24, - commentCount: 0, - showLabel: true - }; + render() { + const { + translate, + commentCount, + onClick, + showLabel, + tagName: containerTag, + } = this.props; - render() { - const { - translate, - commentCount, - onClick, - showLabel, - tagName: containerTag, - } = this.props; - - return React.createElement( - containerTag, { - className: 'comment-button', - onClick - }, - , - - { commentCount > 0 && - { commentCount } - } - { showLabel && commentCount > 0 && - - { translate( 'Comment', 'Comments', { count: commentCount } ) } - - } - - ); - } + return React.createElement( + containerTag, + { + className: 'comment-button', + onClick, + }, + , + + {commentCount > 0 && + {commentCount}} + {showLabel && + commentCount > 0 && + + {translate('Comment', 'Comments', { count: commentCount })} + } + + ); + } } -const mapStateToProps = ( state, ownProps ) => { - const { - post: { - site_ID: siteId, - ID: postId, - } = {}, - commentCount, - } = ownProps; +const mapStateToProps = (state, ownProps) => { + const { + post: { + site_ID: siteId, + ID: postId, + } = {}, + commentCount, + } = ownProps; - return { - commentCount: getPostTotalCommentsCount( state, siteId, postId ) || commentCount - }; + return { + commentCount: getPostTotalCommentsCount(state, siteId, postId) || commentCount, + }; }; -export default connect( mapStateToProps )( localize( CommentButton ) ); +export default connect(mapStateToProps)(localize(CommentButton)); diff --git a/client/blocks/comments/comment-count.jsx b/client/blocks/comments/comment-count.jsx index 57e317279382d..d54dd4aa8d71f 100644 --- a/client/blocks/comments/comment-count.jsx +++ b/client/blocks/comments/comment-count.jsx @@ -8,33 +8,29 @@ import React from 'react'; */ import { localize } from 'i18n-calypso'; -const CommentCount = ( { count, translate } ) => { - let countPhrase; - if ( count > 0 ) { - countPhrase = translate( - '%(commentCount)d comment', - '%(commentCount)d comments', - { - count, - args: { - commentCount: count - } - } - ); - } else { - countPhrase = translate( 'No comments' ); - } +const CommentCount = ({ count, translate }) => { + let countPhrase; + if (count > 0) { + countPhrase = translate('%(commentCount)d comment', '%(commentCount)d comments', { + count, + args: { + commentCount: count, + }, + }); + } else { + countPhrase = translate('No comments'); + } - return ( -
- { countPhrase } - { count === 0 && translate( ' - Add the first! ' ) } -
- ); + return ( +
+ {countPhrase} + {count === 0 && translate(' - Add the first! ')} +
+ ); }; CommentCount.propTypes = { - count: React.PropTypes.number.isRequired + count: React.PropTypes.number.isRequired, }; -export default localize( CommentCount ); +export default localize(CommentCount); diff --git a/client/blocks/comments/comment-likes.jsx b/client/blocks/comments/comment-likes.jsx index 335d50aa7cfce..ab87644052322 100644 --- a/client/blocks/comments/comment-likes.jsx +++ b/client/blocks/comments/comment-likes.jsx @@ -11,72 +11,73 @@ import { translate } from 'i18n-calypso'; * Internal dependencies */ import LikeButton from 'blocks/like-button/button'; -import { - recordAction, - recordGaEvent, - recordTrack -} from 'reader/stats'; -import { - likeComment, - unlikeComment -} from 'state/comments/actions'; +import { recordAction, recordGaEvent, recordTrack } from 'reader/stats'; +import { likeComment, unlikeComment } from 'state/comments/actions'; import { getCommentLike } from 'state/comments/selectors'; class CommentLikeButtonContainer extends React.Component { - constructor() { - super(); - this.boundHandleLikeToggle = this.handleLikeToggle.bind( this ); - } + constructor() { + super(); + this.boundHandleLikeToggle = this.handleLikeToggle.bind(this); + } - handleLikeToggle( liked ) { - if ( liked ) { - this.props.likeComment( this.props.siteId, this.props.postId, this.props.commentId ); - } else { - this.props.unlikeComment( this.props.siteId, this.props.postId, this.props.commentId ); - } + handleLikeToggle(liked) { + if (liked) { + this.props.likeComment(this.props.siteId, this.props.postId, this.props.commentId); + } else { + this.props.unlikeComment(this.props.siteId, this.props.postId, this.props.commentId); + } - recordAction( liked ? 'liked_comment' : 'unliked_comment' ); - recordGaEvent( liked ? 'Clicked Comment Like' : 'Clicked Comment Unlike' ); - recordTrack( 'calypso_reader_' + ( liked ? 'liked' : 'unliked' ) + '_comment', { - blog_id: this.props.siteId, - comment_id: this.props.commentId - } ); - } + recordAction(liked ? 'liked_comment' : 'unliked_comment'); + recordGaEvent(liked ? 'Clicked Comment Like' : 'Clicked Comment Unlike'); + recordTrack('calypso_reader_' + (liked ? 'liked' : 'unliked') + '_comment', { + blog_id: this.props.siteId, + comment_id: this.props.commentId, + }); + } - render() { - const props = pick( this.props, [ 'showZeroCount', 'tagName' ] ); - const likeCount = this.props.commentLike.get( 'like_count' ); - const iLike = this.props.commentLike.get( 'i_like' ); - const likedLabel = translate( 'Liked' ); + render() { + const props = pick(this.props, ['showZeroCount', 'tagName']); + const likeCount = this.props.commentLike.get('like_count'); + const iLike = this.props.commentLike.get('i_like'); + const likedLabel = translate('Liked'); - return ; - } + return ( + + ); + } } CommentLikeButtonContainer.propTypes = { - siteId: React.PropTypes.number.isRequired, - postId: React.PropTypes.number.isRequired, - commentId: React.PropTypes.number.isRequired, - showZeroCount: React.PropTypes.bool, - tagName: React.PropTypes.string, + siteId: React.PropTypes.number.isRequired, + postId: React.PropTypes.number.isRequired, + commentId: React.PropTypes.number.isRequired, + showZeroCount: React.PropTypes.bool, + tagName: React.PropTypes.string, - // connected props: - commentLike: React.PropTypes.object.isRequired, // Immutable.Map - likeComment: React.PropTypes.func.isRequired, - unlikeComment: React.PropTypes.func.isRequired + // connected props: + commentLike: React.PropTypes.object.isRequired, // Immutable.Map + likeComment: React.PropTypes.func.isRequired, + unlikeComment: React.PropTypes.func.isRequired, }; export default connect( - ( state, props ) => ( { - commentLike: getCommentLike( state, props.siteId, props.postId, props.commentId ) - } ), - ( dispatch ) => bindActionCreators( { - likeComment, - unlikeComment - }, dispatch ) -)( CommentLikeButtonContainer ); + (state, props) => ({ + commentLike: getCommentLike(state, props.siteId, props.postId, props.commentId), + }), + dispatch => + bindActionCreators( + { + likeComment, + unlikeComment, + }, + dispatch + ) +)(CommentLikeButtonContainer); diff --git a/client/blocks/comments/form.jsx b/client/blocks/comments/form.jsx index 4139615b63316..5249a2b897fb7 100644 --- a/client/blocks/comments/form.jsx +++ b/client/blocks/comments/form.jsx @@ -14,246 +14,261 @@ import { translate } from 'i18n-calypso'; import AutoDirection from 'components/auto-direction'; import Gravatar from 'components/gravatar'; import Notice from 'components/notice'; -import { - getCurrentUser -} from 'state/current-user/selectors'; -import { - writeComment, - removeComment -} from 'state/comments/actions'; -import { - recordAction, - recordGaEvent, - recordTrackForPost -} from 'reader/stats'; +import { getCurrentUser } from 'state/current-user/selectors'; +import { writeComment, removeComment } from 'state/comments/actions'; +import { recordAction, recordGaEvent, recordTrackForPost } from 'reader/stats'; import { isCommentableDiscoverPost } from 'blocks/comments/helper'; class PostCommentForm extends React.Component { - constructor( props ) { - super(); - - this.state = { - commentText: props.commentText || '', - haveFocus: false - }; - - // bind event handlers to this instance - Object.getOwnPropertyNames( PostCommentForm.prototype ) - .filter( ( prop ) => prop.indexOf( 'handle' ) === 0 ) - .filter( ( prop ) => typeof this[ prop ] === 'function' ) - .forEach( ( prop ) => this[ prop ] = this[ prop ].bind( this ) ); - } - - componentWillReceiveProps( nextProps ) { - this.setState( { - commentText: nextProps.commentText || '' - } ); - } - - componentDidMount() { - // If it's a reply, give the input focus if commentText exists ( can not exist if comments are closed ) - if ( this.props.parentCommentID && this._textareaNode ) { - this._textareaNode.focus(); - } - } - - componentDidUpdate() { - const commentTextNode = this.refs.commentText; - - if ( ! commentTextNode ) { - return; - } - - const commentText = this.getCommentText(); - const currentHeight = parseInt( commentTextNode.style.height, 10 ) || 0; - commentTextNode.style.height = commentText.length ? Math.max( commentTextNode.scrollHeight, currentHeight ) + 'px' : null; - } - - handleTextAreaNode( textareaNode ) { - this._textareaNode = textareaNode; - } - - handleSubmit( event ) { - event.preventDefault(); - this.submit(); - } - - handleKeyDown( event ) { - // Use Ctrl+Enter to submit comment - if ( event.keyCode === 13 && ( event.ctrlKey || event.metaKey ) ) { - event.preventDefault(); - this.submit(); - } - - // Use ESC to remove the erroneous comment placeholder and just start over - if ( event.keyCode === 27 ) { - if ( this.props.placeholderId ) { - // sync the text to the upper level so it won't be lost - this.props.onUpdateCommentText( this.props.commentText ); - // remove the comment - this.props.removeComment( this.props.post.site_ID, this.props.post.ID, this.props.placeholderId ); - } - } - } - - handleFocus() { - this.setState( { haveFocus: true } ); - } - - handleTextChange( event ) { - const commentText = event.target.value; - - this.setState( { commentText } ); - - // Update the comment text in the container's state - this.props.onUpdateCommentText( commentText ); - } - - resetCommentText() { - this.setState( { commentText: '' } ); + constructor(props) { + super(); + + this.state = { + commentText: props.commentText || '', + haveFocus: false, + }; + + // bind event handlers to this instance + Object.getOwnPropertyNames(PostCommentForm.prototype) + .filter(prop => prop.indexOf('handle') === 0) + .filter(prop => typeof this[prop] === 'function') + .forEach(prop => this[prop] = this[prop].bind(this)); + } + + componentWillReceiveProps(nextProps) { + this.setState({ + commentText: nextProps.commentText || '', + }); + } + + componentDidMount() { + // If it's a reply, give the input focus if commentText exists ( can not exist if comments are closed ) + if (this.props.parentCommentID && this._textareaNode) { + this._textareaNode.focus(); + } + } + + componentDidUpdate() { + const commentTextNode = this.refs.commentText; + + if (!commentTextNode) { + return; + } + + const commentText = this.getCommentText(); + const currentHeight = parseInt(commentTextNode.style.height, 10) || 0; + commentTextNode.style.height = commentText.length + ? Math.max(commentTextNode.scrollHeight, currentHeight) + 'px' + : null; + } + + handleTextAreaNode(textareaNode) { + this._textareaNode = textareaNode; + } + + handleSubmit(event) { + event.preventDefault(); + this.submit(); + } + + handleKeyDown(event) { + // Use Ctrl+Enter to submit comment + if (event.keyCode === 13 && (event.ctrlKey || event.metaKey)) { + event.preventDefault(); + this.submit(); + } + + // Use ESC to remove the erroneous comment placeholder and just start over + if (event.keyCode === 27) { + if (this.props.placeholderId) { + // sync the text to the upper level so it won't be lost + this.props.onUpdateCommentText(this.props.commentText); + // remove the comment + this.props.removeComment( + this.props.post.site_ID, + this.props.post.ID, + this.props.placeholderId + ); + } + } + } + + handleFocus() { + this.setState({ haveFocus: true }); + } + + handleTextChange(event) { + const commentText = event.target.value; + + this.setState({ commentText }); // Update the comment text in the container's state - this.props.onUpdateCommentText( '' ); - } - - hasCommentText() { - return this.state.commentText.trim().length > 0; - } - - submit() { - const post = this.props.post; - const commentText = this.state.commentText.trim(); - - if ( ! commentText ) { - this.resetCommentText(); // Clean up any newlines - return false; - } - - if ( this.props.placeholderId ) { - this.props.removeComment( post.site_ID, post.ID, this.props.placeholderId ); - } - this.props.writeComment( commentText, post.site_ID, post.ID, this.props.parentCommentID ); - - recordAction( 'posted_comment' ); - recordGaEvent( 'Clicked Post Comment Button' ); - recordTrackForPost( 'calypso_reader_article_commented_on', post, { - parent_post_id: this.props.parentCommentID ? this.props.parentCommentID : undefined - } ); - - this.resetCommentText(); - - // Resets the active reply comment in PostCommentList - this.props.onCommentSubmit(); - - return true; - } - - renderError() { - const error = this.props.error; - let message; - - if ( ! error ) { - return null; - } - - switch ( error.error ) { - case 'comment_duplicate': - message = translate( "Duplicate comment detected. It looks like you've already said that!" ); - break; - - default: - message = translate( 'Sorry - there was a problem posting your comment.' ); - break; - } - - return ; - } - - render() { - const post = this.props.post; - - // Don't display the form if comments are closed - if ( post && post.discussion && post.discussion.comments_open === false && ! isCommentableDiscoverPost( post ) ) { - // If we already have some comments, show a 'comments closed message' - if ( post.discussion.comment_count && post.discussion.comment_count > 0 ) { - return

{ translate( 'Comments are closed.' ) }

; - } - - return null; - } - - const buttonClasses = classNames( { - 'is-active': this.hasCommentText(), - 'is-visible': this.state.haveFocus || this.hasCommentText() - } ); - - const expandingAreaClasses = classNames( { - focused: this.state.haveFocus, - 'expanding-area': true - } ); - - // How auto expand works for the textarea is covered in this article: - // http://alistapart.com/article/expanding-text-areas-made-elegant - return ( -
-
- -