From f2c5db6c8202a7cab09384c1d2b691882d977ae0 Mon Sep 17 00:00:00 2001 From: Dixita Dusara Date: Wed, 30 Jan 2019 22:16:48 +0530 Subject: [PATCH 01/17] Fixed wording for the color picker saturation (#13479) Related: #13444 This pull request seeks to fix wording for the color picker saturation. Let me know if any changes require. Thank you, --- packages/components/src/color-picker/saturation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/color-picker/saturation.js b/packages/components/src/color-picker/saturation.js index 8e86655025e920..90c6f8661bb90b 100644 --- a/packages/components/src/color-picker/saturation.js +++ b/packages/components/src/color-picker/saturation.js @@ -175,7 +175,7 @@ export class Saturation extends Component { className="screen-reader-text" id={ `color-picker-saturation-${ instanceId }` }> { __( - 'Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to increase saturation, and right to decrease saturation.' + 'Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation.' ) } From a85767a12f456e99c91ccb1f6a0d01f0ea32624b Mon Sep 17 00:00:00 2001 From: etoledom Date: Wed, 30 Jan 2019 21:35:37 +0100 Subject: [PATCH 02/17] Image settings button (#13597) * rnmobile: Implement image settings button using InspectorControls.Slot pattern. * rnmobile: Add missing semicolon --- packages/block-library/src/image/edit.native.js | 17 ++++++++++++++++- packages/editor/src/components/index.native.js | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 6c5fad9b7b05ec..7413978f2e0123 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -14,7 +14,7 @@ import { /** * Internal dependencies */ -import { MediaPlaceholder, RichText, BlockControls } from '@wordpress/editor'; +import { MediaPlaceholder, RichText, BlockControls, InspectorControls } from '@wordpress/editor'; import { Toolbar, ToolbarButton, Spinner } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import ImageSize from './image-size'; @@ -143,6 +143,10 @@ export default class ImageEdit extends React.Component { ); } + const onImageSettingsButtonPressed = () => { + + }; + const toolbarEditButton = ( ); + const inlineToolbarButtons = ( + + ); + const showSpinner = this.state.isUploadInProgress; const opacity = this.state.isUploadInProgress ? 0.3 : 1; const progress = this.state.progress * 100; @@ -163,6 +175,9 @@ export default class ImageEdit extends React.Component { { toolbarEditButton } + + { inlineToolbarButtons } + { ( sizes ) => { const { diff --git a/packages/editor/src/components/index.native.js b/packages/editor/src/components/index.native.js index d226b4fe46480c..07bd4c9993e6d2 100644 --- a/packages/editor/src/components/index.native.js +++ b/packages/editor/src/components/index.native.js @@ -10,3 +10,4 @@ export { default as DefaultBlockAppender } from './default-block-appender'; export { default as PostTitle } from './post-title'; export { default as EditorHistoryRedo } from './editor-history/redo'; export { default as EditorHistoryUndo } from './editor-history/undo'; +export { default as InspectorControls } from './inspector-controls'; From b9e9aedda252e91bcecf3a34a19cf8af79bbdef2 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 30 Jan 2019 15:38:10 -0500 Subject: [PATCH 03/17] eslint-plugin: Add rule `no-unused-vars-before-return` (#12828) * scripts: Bump ESLint dependency to 5.10.x * eslint-plugin: Add rule `no-unused-vars-before-return` * eslint-plugin: Rephrase return-unused message for declarator * Update error message in the unit test to reflect code changes * Scripts: Include Migration Guide link for ESLint major bump CHANGELOG note --- package-lock.json | 384 ++++++++++-------- packages/eslint-plugin/CHANGELOG.md | 4 + packages/eslint-plugin/README.md | 12 +- packages/eslint-plugin/configs/custom.js | 4 + .../rules/no-unused-vars-before-return.md | 31 ++ packages/eslint-plugin/index.js | 1 + .../__tests__/no-unused-vars-before-return.js | 45 ++ packages/eslint-plugin/rules/index.js | 1 + .../rules/no-unused-vars-before-return.js | 56 +++ packages/scripts/CHANGELOG.md | 6 +- packages/scripts/package.json | 2 +- 11 files changed, 364 insertions(+), 182 deletions(-) create mode 100644 packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md create mode 100644 packages/eslint-plugin/rules/__tests__/no-unused-vars-before-return.js create mode 100644 packages/eslint-plugin/rules/index.js create mode 100644 packages/eslint-plugin/rules/no-unused-vars-before-return.js diff --git a/package-lock.json b/package-lock.json index 30246ca516f389..83491b6775a238 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2782,7 +2782,7 @@ "chalk": "^2.4.1", "check-node-version": "^3.1.1", "cross-spawn": "^5.1.0", - "eslint": "^4.19.1", + "eslint": "^5.12.1", "jest": "^23.6.0", "jest-puppeteer": "3.2.1", "npm-package-json-lint": "^3.3.1", @@ -4331,23 +4331,6 @@ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", "dev": true }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - }, - "dependencies": { - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - } - } - }, "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", @@ -4475,9 +4458,9 @@ "dev": true }, "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, "check-node-version": { @@ -6280,21 +6263,6 @@ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6807,76 +6775,146 @@ } }, "eslint": { - "version": "4.19.1", - "resolved": "http://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.12.1.tgz", + "integrity": "sha512-54NV+JkTpTu0d8+UYSA8mMKAG4XAsaOrozA9rCW7tgneg1mevcL7wIotPC+fZ0SkWwdhNqoXoxnQCTBp7UvTsg==", "dev": true, "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", + "@babel/code-frame": "^7.0.0", + "ajv": "^6.5.3", "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", + "espree": "^5.0.0", + "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", + "inquirer": "^6.1.0", + "js-yaml": "^3.12.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", "pluralize": "^7.0.0", "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" + "strip-json-comments": "^2.0.1", + "table": "^5.0.2", + "text-table": "^0.2.0" }, "dependencies": { - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "acorn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz", + "integrity": "sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==", "dev": true }, - "regexpp": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", "dev": true }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "ajv": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" } + }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz", + "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true } } }, @@ -6962,6 +7000,12 @@ "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -7414,14 +7458,25 @@ } }, "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", "dev": true, "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } } }, "extglob": { @@ -7879,14 +7934,14 @@ } }, "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", "dev": true, "requires": { "circular-json": "^0.3.1", - "del": "^2.0.2", "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", "write": "^0.2.1" } }, @@ -9088,20 +9143,6 @@ "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", "dev": true }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, "globjoin": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", @@ -9537,6 +9578,24 @@ "minimatch": "^3.0.4" } }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, "import-lazy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", @@ -9621,25 +9680,41 @@ } }, "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", + "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.0", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", - "external-editor": "^2.0.4", + "external-editor": "^3.0.0", "figures": "^2.0.0", - "lodash": "^4.3.0", + "lodash": "^4.17.10", "mute-stream": "0.0.7", "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", + "rxjs": "^6.1.0", "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", + "strip-ansi": "^5.0.0", "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + } + } } }, "interpret": { @@ -9942,32 +10017,6 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - }, - "dependencies": { - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - } - } - }, "is-path-inside": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.0.0.tgz", @@ -14564,6 +14613,23 @@ "readable-stream": "^2.1.5" } }, + "parent-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz", + "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", + "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", + "dev": true + } + } + }, "parse-asn1": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", @@ -17356,6 +17422,12 @@ "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "regexpu-core": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.2.0.tgz", @@ -17556,24 +17628,6 @@ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - } - } - }, "requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -17771,21 +17825,6 @@ "integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=", "dev": true }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" - } - }, "rxjs": { "version": "6.3.3", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", @@ -18280,15 +18319,6 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, "slide": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 0ab0b2624c58d8..775abcac663058 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -4,6 +4,10 @@ - The `esnext` and `recommended` rulesets now enforce [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand) +### New Features + +- New Rule: [`@wordpress/no-unused-vars-before-return`](https://github.com/WordPress/gutenberg/blob/master/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md) + ## 1.0.0 (2018-12-12) ### New Features diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 3463e97d84024b..1f001411b73192 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -10,7 +10,7 @@ Install the module npm install @wordpress/eslint-plugin --save-dev ``` -### Usage +## Usage To opt-in to the default configuration, extend your own project's `.eslintrc` file: @@ -24,7 +24,7 @@ Refer to the [ESLint documentation on Shareable Configs](http://eslint.org/docs/ The `recommended` preset will include rules governing an ES2015+ environment, and includes rules from the [`eslint-plugin-jsx-a11y`](https://github.com/evcohen/eslint-plugin-jsx-a11y) and [`eslint-plugin-react`](https://github.com/yannickcr/eslint-plugin-react) projects. -#### Rulesets +### Rulesets Alternatively, you can opt-in to only the more granular rulesets offered by the plugin. These include: @@ -45,7 +45,13 @@ These rules can be used additively, so you could extend both `esnext` and `custo The granular rulesets will not define any environment globals. As such, if they are required for your project, you will need to define them yourself. -#### Legacy +### Rules + +Rule|Description +---|--- +[no-unused-vars-before-return](docs/rules/no-unused-vars-before-return.md)|Disallow assigning variable values if unused before a return + +### Legacy If you are using WordPress' `.jshintrc` JSHint configuration and you would like to take the first step to migrate to an ESLint equivalent it is also possible to define your own project's `.eslintrc` file as: diff --git a/packages/eslint-plugin/configs/custom.js b/packages/eslint-plugin/configs/custom.js index 0318c85c324c9e..5691c3c5d0c2ba 100644 --- a/packages/eslint-plugin/configs/custom.js +++ b/packages/eslint-plugin/configs/custom.js @@ -1,5 +1,9 @@ module.exports = { + plugins: [ + '@wordpress', + ], rules: { + '@wordpress/no-unused-vars-before-return': 'error', 'no-restricted-syntax': [ 'error', { diff --git a/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md b/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md new file mode 100644 index 00000000000000..7dba90d4059738 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md @@ -0,0 +1,31 @@ +# Avoid assigning variable values if unused before a return (no-unused-vars-before-return) + +To avoid wastefully computing the result of a function call when assigning a variable value, the variable should be declared as late as possible. In practice, if a function includes an early return path, any variable declared prior to the `return` must be referenced at least once. Otherwise, in the condition which satisfies that return path, the declared variable is effectively considered dead code. This can have a performance impact when the logic performed in assigning the value is non-trivial. + +## Rule details + +The following patterns are considered warnings: + +```js +function example( number ) { + const foo = doSomeCostlyOperation(); + if ( number > 10 ) { + return number + 1; + } + + return number + foo; +} +``` + +The following patterns are not considered warnings: + +```js +function example( number ) { + if ( number > 10 ) { + return number + 1; + } + + const foo = doSomeCostlyOperation(); + return number + foo; +} +``` diff --git a/packages/eslint-plugin/index.js b/packages/eslint-plugin/index.js index 0933aba1cc826b..fcba80b48203aa 100644 --- a/packages/eslint-plugin/index.js +++ b/packages/eslint-plugin/index.js @@ -1,3 +1,4 @@ module.exports = { configs: require( './configs' ), + rules: require( './rules' ), }; diff --git a/packages/eslint-plugin/rules/__tests__/no-unused-vars-before-return.js b/packages/eslint-plugin/rules/__tests__/no-unused-vars-before-return.js new file mode 100644 index 00000000000000..394b88728954df --- /dev/null +++ b/packages/eslint-plugin/rules/__tests__/no-unused-vars-before-return.js @@ -0,0 +1,45 @@ +/** + * External dependencies + */ +import { RuleTester } from 'eslint'; + +/** + * Internal dependencies + */ +import rule from '../no-unused-vars-before-return'; + +const ruleTester = new RuleTester( { + parserOptions: { + ecmaVersion: 6, + }, +} ); + +ruleTester.run( 'no-unused-vars-before-return', rule, { + valid: [ + { + code: ` +function example( number ) { + if ( number > 10 ) { + return number + 1; + } + + const foo = doSomeCostlyOperation(); + return number + foo; +}`, + }, + ], + invalid: [ + { + code: ` +function example( number ) { + const foo = doSomeCostlyOperation(); + if ( number > 10 ) { + return number + 1; + } + + return number + foo; +}`, + errors: [ { message: 'Variables should not be assigned until just prior its first reference. An early return statement may leave this variable unused.' } ], + }, + ], +} ); diff --git a/packages/eslint-plugin/rules/index.js b/packages/eslint-plugin/rules/index.js new file mode 100644 index 00000000000000..035c09a8fa767a --- /dev/null +++ b/packages/eslint-plugin/rules/index.js @@ -0,0 +1 @@ +module.exports = require( 'requireindex' )( __dirname ); diff --git a/packages/eslint-plugin/rules/no-unused-vars-before-return.js b/packages/eslint-plugin/rules/no-unused-vars-before-return.js new file mode 100644 index 00000000000000..012b7172bdbb0e --- /dev/null +++ b/packages/eslint-plugin/rules/no-unused-vars-before-return.js @@ -0,0 +1,56 @@ +module.exports = { + meta: { + type: 'problem', + schema: [], + }, + create( context ) { + return { + ReturnStatement( node ) { + let functionScope = context.getScope(); + while ( functionScope.type !== 'function' && functionScope.upper ) { + functionScope = functionScope.upper; + } + + if ( ! functionScope ) { + return; + } + + for ( const variable of functionScope.variables ) { + const declaratorCandidate = variable.defs.find( ( def ) => { + return ( + def.node.type === 'VariableDeclarator' && + // Allow declarations which are not initialized. + def.node.init && + // Target function calls as "expensive". + def.node.init.type === 'CallExpression' && + // Allow unused if part of an object destructuring. + def.node.id.type !== 'ObjectPattern' && + // Only target assignments preceding `return`. + def.node.end < node.end + ); + } ); + + if ( ! declaratorCandidate ) { + continue; + } + + // The first entry in `references` is the declaration + // itself, which can be ignored. + const isUsedBeforeReturn = variable.references.slice( 1 ).some( ( reference ) => { + return reference.identifier.end < node.end; + } ); + + if ( isUsedBeforeReturn ) { + continue; + } + + context.report( + declaratorCandidate.node, + 'Variables should not be assigned until just prior its first reference. ' + + 'An early return statement may leave this variable unused.' + ); + } + }, + }; + }, +}; diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 9e297b5b652d20..fe24a86900ee07 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -1,4 +1,8 @@ -## 2.6.0 (Unreleased) +## 3.0.0 (Unreleased) + +### Breaking Changes + +- The bundled `eslint` dependency has been updated from requiring `^4.19.1` to requiring `^5.12.1` (see [Migration Guide](https://eslint.org/docs/user-guide/migrating-to-5.0.0)). ### New Features diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 86d4211b874d5e..8aaf6e8ee7ac67 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -38,7 +38,7 @@ "chalk": "^2.4.1", "check-node-version": "^3.1.1", "cross-spawn": "^5.1.0", - "eslint": "^4.19.1", + "eslint": "^5.12.1", "jest": "^23.6.0", "jest-puppeteer": "3.2.1", "npm-package-json-lint": "^3.3.1", From 3fd221845bfb6b3c553368b8b3cfbcc29452932f Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 30 Jan 2019 17:10:48 -0500 Subject: [PATCH 04/17] Plugin: Remove `user_can_richedit` filtering (#13608) --- lib/client-assets.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/client-assets.php b/lib/client-assets.php index 469310edbe118c..96986825e9bc27 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -893,13 +893,6 @@ function gutenberg_editor_scripts_and_styles( $hook ) { 'after' ); - // Ignore Classic Editor's `rich_editing` user option, aka "Disable visual - // editor". Forcing this to be true guarantees that TinyMCE and its plugins - // are available in Gutenberg. Fixes - // https://github.com/WordPress/gutenberg/issues/5667. - $user_can_richedit = user_can_richedit(); - add_filter( 'user_can_richedit', '__return_true' ); - wp_enqueue_script( 'wp-edit-post' ); wp_enqueue_script( 'wp-format-library' ); wp_enqueue_style( 'wp-format-library' ); @@ -1134,7 +1127,7 @@ function gutenberg_editor_scripts_and_styles( $hook ) { 'allowedMimeTypes' => get_allowed_mime_types(), 'styles' => $styles, 'imageSizes' => gutenberg_get_available_image_sizes(), - 'richEditingEnabled' => $user_can_richedit, + 'richEditingEnabled' => user_can_richedit(), // Ideally, we'd remove this and rely on a REST API endpoint. 'postLock' => $lock_details, From 6e4e9aa3f92ec6e568084630c295f020da9bb13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Thu, 31 Jan 2019 11:24:11 +0100 Subject: [PATCH 05/17] Docs: Add clarification about git workflow (#13534) * Docs: Add clarification about git workflow * Update git-workflow.md * Update git-workflow.md * Reword paragraph on merging vs. rebasing * Add references * Add fork section * Clarify link to section "Perform a rebase" * Apply suggestions from code review Co-Authored-By: gziolo --- docs/contributors/git-workflow.md | 44 ++++++++++++++++++++++ docs/contributors/repository-management.md | 2 +- docs/manifest.json | 18 ++++++--- docs/toc.json | 3 +- 4 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 docs/contributors/git-workflow.md diff --git a/docs/contributors/git-workflow.md b/docs/contributors/git-workflow.md new file mode 100644 index 00000000000000..f159b46126e617 --- /dev/null +++ b/docs/contributors/git-workflow.md @@ -0,0 +1,44 @@ +# Git Workflow + +## Keeping Your Branch Up To Date + +When many different people are working on a project simultaneously, pull requests can go stale quickly. A "stale" pull request is one that is no longer up to date with the main line of development, and it needs to be updated before it can be merged into the project. + +There are two ways to do this: merging and rebasing. In Gutenberg, the recommendation is to rebase. Rebasing means rewriting your changes as if they're happening on top of the main line of development. This ensures the commit history is always clean and linear. Rebasing can be performed as many times as needed while you're working on a pull request. **Do share your work early on** by opening a pull request and keeping your history rebase as you progress. + +The main line of development is known as the `master` branch. If you have a pull-request branch that cannot be merged into `master` due to a conflict (this can happen for long-running pull requests), then in the course of rebasing you'll have to manually resolve any conflicts in your local copy. Learn more in [section _Perform a rebase_](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request#perform-a-rebase) of _How to Rebase a Pull Request_. + +Once you have resolved any conflicts locally you can update the pull request with `git push --force-with-lease`. Using the `--force-with-lease` parameter is important to guarantee that you don't accidentally overwrite someone else's work. + +To sum it up, you need to fetch any new changes in the repository, rebase your branch on top of `master`, and push the result back to the repository. These are the corresponding commands: + +```sh +git fetch +git rebase master +git push --force-with-lease your-branch-name +``` + +## Keeping Your Fork Up To Date + +Working on pull request starts with forking the Gutenberg repository, your separate working copy. Which can easily go out of sync as new pull requests are merged into the main repository. Here your working repository is a `fork` and the main Gutenberg repository is `upstream`. When working on new pull request you should always update your fork before you do `git checkout -b my-new-branch` to work on a feature or fix. + +To sync your fork you need to fetch the upstream changes and merge them into your fork. These are the corresponding commands: + +``` sh +git fetch upstream +git checkout master +git merge upstream/master +``` + +This will update you local copy to update your fork on github push your changes + +``` +git push +``` + +The above commands will update your `master` branch from _upstream_. To update any other branch replace `master` with the respective branch name. + + +## References +- https://git-scm.com/book/en/v2 +- https://help.github.com/categories/collaborating-with-issues-and-pull-requests/ diff --git a/docs/contributors/repository-management.md b/docs/contributors/repository-management.md index 08b47e1777f2a2..7eaa1cb28661e0 100644 --- a/docs/contributors/repository-management.md +++ b/docs/contributors/repository-management.md @@ -83,7 +83,6 @@ When reviewing issues, here are some steps you can perform: Gutenberg follows a feature branch pull request workflow for all code and documentation changes. At a high-level, the process looks like this: - 1. Check out a new feature branch locally. 2. Make your changes, testing thoroughly. 3. Commit your changes when you’re happy with them, and push the branch. @@ -127,6 +126,7 @@ A pull request can generally be merged once it is: - Vetted against all potential edge cases. - Changelog entries were properly added. - Reviewed by someone other than the original author. +- [Rebased](/docs/contributors/git-workflow.md#keeping-your-branch-up-to-date) onto the latest version of the master branch. The final pull request merge decision is made by the **@wordpress/gutenberg-core** team. diff --git a/docs/manifest.json b/docs/manifest.json index 35964c417ab5ec..6e6dbd2e40251c 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -413,18 +413,24 @@ "markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/docs/contributors/coding-guidelines.md", "parent": "develop" }, - { - "title": "Block Grammar", - "slug": "grammar", - "markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/docs/contributors/grammar.md", - "parent": "develop" - }, { "title": "Testing Overview", "slug": "testing-overview", "markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/docs/contributors/testing-overview.md", "parent": "develop" }, + { + "title": "Git Workflow", + "slug": "git-workflow", + "markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/docs/contributors/git-workflow.md", + "parent": "develop" + }, + { + "title": "Block Grammar", + "slug": "grammar", + "markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/docs/contributors/grammar.md", + "parent": "develop" + }, { "title": "Scripts", "slug": "scripts", diff --git a/docs/toc.json b/docs/toc.json index 4e06b65d552ce7..14bed66d0a75e7 100644 --- a/docs/toc.json +++ b/docs/toc.json @@ -82,8 +82,9 @@ ]}, {"docs/contributors/develop.md": [ {"docs/contributors/coding-guidelines.md": []}, - {"docs/contributors/grammar.md": []}, {"docs/contributors/testing-overview.md": []}, + {"docs/contributors/git-workflow.md": []}, + {"docs/contributors/grammar.md": []}, {"docs/contributors/scripts.md": []}, {"docs/contributors/release.md": []} ]}, From a8dcfb242b3765e0e0a3d615b3cc6b204fd92b32 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Thu, 31 Jan 2019 12:29:05 +0000 Subject: [PATCH 06/17] Fix: Categories Block: hierarchical Dropdown (#13567) Previously higher than second levels categories here rendered multiple times on the categories block, when "Show Hierarchy" and "Display as Dropdown" options here true. This commit fixes that problem. --- packages/block-library/src/categories/edit.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/categories/edit.js b/packages/block-library/src/categories/edit.js index ad1dea3ec55bf4..aee240e7384e69 100644 --- a/packages/block-library/src/categories/edit.js +++ b/packages/block-library/src/categories/edit.js @@ -106,7 +106,8 @@ class CategoriesEdit extends Component { } renderCategoryDropdown() { - const { showHierarchy, instanceId } = this.props; + const { instanceId } = this.props; + const { showHierarchy } = this.props.attributes; const parentId = showHierarchy ? 0 : null; const categories = this.getCategories( parentId ); const selectId = `blocks-category-select-${ instanceId }`; From 7fd6316997acca945899e8bd2fe2e8a5b4e6427b Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Thu, 31 Jan 2019 12:31:53 +0000 Subject: [PATCH 07/17] Add: className prop support to server side render. (#13568) --- .../src/server-side-render/README.md | 30 +++++++++++++++++++ .../src/server-side-render/index.js | 26 +++++++++++++--- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/packages/components/src/server-side-render/README.md b/packages/components/src/server-side-render/README.md index 55b0be7630dabb..df9d75dec8fa4f 100644 --- a/packages/components/src/server-side-render/README.md +++ b/packages/components/src/server-side-render/README.md @@ -8,6 +8,36 @@ ServerSideRender should be regarded as a fallback or legacy mechanism, it is not New blocks should be built in conjunction with any necessary REST API endpoints, so that JavaScript can be used for rendering client-side in the `edit` function. This gives the best user experience, instead of relying on using the PHP `render_callback`. The logic necessary for rendering should be included in the endpoint, so that both the client-side JavaScript and server-side PHP logic should require a minimal amount of differences. +## Props + +### attributes + +An object containing the attributes of the block to be server-side rendered. +E.g: `{ displayAsDropdown: true }`, `{ showHierarchy: true }`, etc... +- Type: `Object` +- Required: No + +### block + +The identifier of the block to be server-side rendered. +Examples: "core/archives", "core/latest-comments", "core/rss", etc... +- Type: `String` +- Required: Yes + +### className + +A class added to the DOM element that wraps the server side rendered block. +Examples: "my-custom-server-side-rendered". +- Type: `String` +- Required: No + +### urlQueryArgs + +Query arguments to apply to the request URL. +E.g: `{ post_id: 12 }`. +- Type: `Object` +- Required: No + ## Usage Render core/archives preview. diff --git a/packages/components/src/server-side-render/index.js b/packages/components/src/server-side-render/index.js index ed11eac1c518bf..71d649dfbf6440 100644 --- a/packages/components/src/server-side-render/index.js +++ b/packages/components/src/server-side-render/index.js @@ -85,24 +85,42 @@ export class ServerSideRender extends Component { render() { const response = this.state.response; + const { className } = this.props; if ( ! response ) { return ( - + + + ); } else if ( response.error ) { // translators: %s: error message describing the problem const errorMessage = sprintf( __( 'Error loading block: %s' ), response.errorMsg ); return ( - { errorMessage } + + { errorMessage } + ); } else if ( ! response.length ) { return ( - { __( 'No results found.' ) } + + { __( 'No results found.' ) } + ); } return ( - { response } + + { response } + ); } } From bebda205b2039b39457aa3d6f20e275789ba0b57 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Thu, 31 Jan 2019 16:17:13 +0000 Subject: [PATCH 08/17] Make clickOnMoreMenuItem not dependent on aria labels (#13166) The clickOnMoreMenuItem end 2 end test util was dependent on aria labels being present on each menu item. This aria labels are redundant and just duplicate the inner text menu item, they will be removed as soon as https://github.com/WordPress/gutenberg/pull/12955 is merged. This commit updates an end 2 end test util that relied on this aria labels being present. This way we will make sure tests pass on https://github.com/WordPress/gutenberg/pull/12955 as soon as this PR is merged. ## How has this been tested? I verified the end 2 end tests pass. I reverted all snapshot updates in https://github.com/WordPress/gutenberg/pull/12955 and merge that PR with this and I checked the end 2 end tests continue to pass. --- .../src/click-on-more-menu-item.js | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/e2e-test-utils/src/click-on-more-menu-item.js b/packages/e2e-test-utils/src/click-on-more-menu-item.js index a71cf13f1e12c0..0465441ec64965 100644 --- a/packages/e2e-test-utils/src/click-on-more-menu-item.js +++ b/packages/e2e-test-utils/src/click-on-more-menu-item.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { first } from 'lodash'; + /** * Clicks on More Menu item, searches for the button with the text provided and clicks it. * @@ -7,7 +12,18 @@ export async function clickOnMoreMenuItem( buttonLabel ) { await expect( page ).toClick( '.edit-post-more-menu [aria-label="Show more tools & options"]' ); - await page.click( - `.edit-post-more-menu__content button[aria-label="${ buttonLabel }"]` - ); + const moreMenuContainerSelector = + '//*[contains(concat(" ", @class, " "), " edit-post-more-menu__content ")]'; + let elementToClick = first( await page.$x( + `${ moreMenuContainerSelector }//button[contains(text(), "${ buttonLabel }")]` + ) ); + // If button is not found, the label should be on the info wrapper. + if ( ! elementToClick ) { + elementToClick = first( await page.$x( + moreMenuContainerSelector + + '//button' + + `/*[contains(concat(" ", @class, " "), " components-menu-item__info-wrapper ")][contains(text(), "${ buttonLabel }")]` + ) ); + } + await elementToClick.click(); } From 22aba0d13e92892086b9e4bca1c31725e059bcd8 Mon Sep 17 00:00:00 2001 From: Marko Savic Date: Thu, 31 Jan 2019 17:48:19 +0100 Subject: [PATCH 09/17] Rnmobile/upload media failed state (#13615) *Implement upload media failed state --- .../block-library/src/image/edit.native.js | 155 +++++++++++------- .../src/image/styles.native.scss | 17 ++ 2 files changed, 111 insertions(+), 61 deletions(-) create mode 100644 packages/block-library/src/image/styles.native.scss diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 7413978f2e0123..fe3fa7c54d2e15 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -2,27 +2,31 @@ * External dependencies */ import React from 'react'; -import { View, Image, TextInput } from 'react-native'; +import { View, ImageBackground, TextInput, Text, TouchableWithoutFeedback } from 'react-native'; import { subscribeMediaUpload, requestMediaPickFromMediaLibrary, requestMediaPickFromDeviceLibrary, requestMediaPickFromDeviceCamera, mediaUploadSync, + requestImageFailedRetryDialog, + requestImageUploadCancelDialog, } from 'react-native-gutenberg-bridge'; /** * Internal dependencies */ import { MediaPlaceholder, RichText, BlockControls, InspectorControls } from '@wordpress/editor'; -import { Toolbar, ToolbarButton, Spinner } from '@wordpress/components'; +import { Toolbar, ToolbarButton, Spinner, Dashicon } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import ImageSize from './image-size'; import { isURL } from '@wordpress/url'; +import styles from './styles.scss'; -const MEDIA_ULOAD_STATE_UPLOADING = 1; -const MEDIA_ULOAD_STATE_SUCCEEDED = 2; -const MEDIA_ULOAD_STATE_FAILED = 3; +const MEDIA_UPLOAD_STATE_UPLOADING = 1; +const MEDIA_UPLOAD_STATE_SUCCEEDED = 2; +const MEDIA_UPLOAD_STATE_FAILED = 3; +const MEDIA_UPLOAD_STATE_RESET = 4; export default class ImageEdit extends React.Component { constructor( props ) { @@ -31,6 +35,7 @@ export default class ImageEdit extends React.Component { this.state = { progress: 0, isUploadInProgress: false, + isUploadFailed: false, }; this.mediaUpload = this.mediaUpload.bind( this ); @@ -38,6 +43,7 @@ export default class ImageEdit extends React.Component { this.removeMediaUploadListener = this.removeMediaUploadListener.bind( this ); this.finishMediaUploadWithSuccess = this.finishMediaUploadWithSuccess.bind( this ); this.finishMediaUploadWithFailure = this.finishMediaUploadWithFailure.bind( this ); + this.onImagePressed = this.onImagePressed.bind( this ); } componentDidMount() { @@ -53,6 +59,16 @@ export default class ImageEdit extends React.Component { this.removeMediaUploadListener(); } + onImagePressed() { + const { attributes } = this.props; + + if ( this.state.isUploadInProgress ) { + requestImageUploadCancelDialog( attributes.id ); + } else if ( attributes.id && ! isURL( attributes.url ) ) { + requestImageFailedRetryDialog( attributes.id ); + } + } + mediaUpload( payload ) { const { attributes } = this.props; @@ -61,15 +77,18 @@ export default class ImageEdit extends React.Component { } switch ( payload.state ) { - case MEDIA_ULOAD_STATE_UPLOADING: - this.setState( { progress: payload.progress, isUploadInProgress: true } ); + case MEDIA_UPLOAD_STATE_UPLOADING: + this.setState( { progress: payload.progress, isUploadInProgress: true, isUploadFailed: false } ); break; - case MEDIA_ULOAD_STATE_SUCCEEDED: + case MEDIA_UPLOAD_STATE_SUCCEEDED: this.finishMediaUploadWithSuccess( payload ); break; - case MEDIA_ULOAD_STATE_FAILED: + case MEDIA_UPLOAD_STATE_FAILED: this.finishMediaUploadWithFailure( payload ); break; + case MEDIA_UPLOAD_STATE_RESET: + this.mediaUploadStateReset( payload ); + break; } } @@ -85,10 +104,15 @@ export default class ImageEdit extends React.Component { finishMediaUploadWithFailure( payload ) { const { setAttributes } = this.props; - setAttributes( { url: payload.mediaUrl, id: payload.mediaId } ); - this.setState( { isUploadInProgress: false } ); + setAttributes( { id: payload.mediaId } ); + this.setState( { isUploadInProgress: false, isUploadFailed: true } ); + } - this.removeMediaUploadListener(); + mediaUploadStateReset( payload ) { + const { setAttributes } = this.props; + + setAttributes( { id: payload.mediaId, url: null } ); + this.setState( { isUploadInProgress: false, isUploadFailed: false } ); } addMediaUploadListener() { @@ -170,55 +194,64 @@ export default class ImageEdit extends React.Component { const progress = this.state.progress * 100; return ( - - { showSpinner && } - - { toolbarEditButton } - - - { inlineToolbarButtons } - - - { ( sizes ) => { - const { - imageWidthWithinContainer, - imageHeightWithinContainer, - } = sizes; - - let finalHeight = imageHeightWithinContainer; - if ( height > 0 && height < imageHeightWithinContainer ) { - finalHeight = height; - } - - let finalWidth = imageWidthWithinContainer; - if ( width > 0 && width < imageWidthWithinContainer ) { - finalWidth = width; - } - - return ( - - - - ); - } } - - { ( ! RichText.isEmpty( caption ) > 0 || isSelected ) && ( - - setAttributes( { caption: newCaption } ) } - /> - - ) } - + + + { showSpinner && } + + { toolbarEditButton } + + + { inlineToolbarButtons } + + + { ( sizes ) => { + const { + imageWidthWithinContainer, + imageHeightWithinContainer, + } = sizes; + + let finalHeight = imageHeightWithinContainer; + if ( height > 0 && height < imageHeightWithinContainer ) { + finalHeight = height; + } + + let finalWidth = imageWidthWithinContainer; + if ( width > 0 && width < imageWidthWithinContainer ) { + finalWidth = width; + } + + return ( + + + { this.state.isUploadFailed && + + + { __( 'Failed to insert media.\nPlease tap for options.' ) } + + } + + + ); + } } + + { ( ! RichText.isEmpty( caption ) > 0 || isSelected ) && ( + + setAttributes( { caption: newCaption } ) } + /> + + ) } + + ); } } diff --git a/packages/block-library/src/image/styles.native.scss b/packages/block-library/src/image/styles.native.scss new file mode 100644 index 00000000000000..833b8126bfc1ad --- /dev/null +++ b/packages/block-library/src/image/styles.native.scss @@ -0,0 +1,17 @@ +.imageContainer { + flex: 1; + justify-content: center; + align-items: center; +} + +.uploadFailedText { + color: #fff; + font-size: 14; + margin-top: 5; +} + +.uploadFailedContainer { + position: absolute; + flex-direction: column; + align-items: center; +} From 62f61631bef4b97be519773eb1b949a847dc493c Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 31 Jan 2019 13:53:07 -0500 Subject: [PATCH 10/17] Plugin: Deprecate gutenberg_add_admin_body_class (#13572) * Plugin: Deprecate gutenberg_add_admin_body_class * Plugin: Reference block-editor-page class for admin class removal --- .../backward-compatibility/deprecations.md | 1 + gutenberg.php | 12 ++++-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/designers-developers/developers/backward-compatibility/deprecations.md b/docs/designers-developers/developers/backward-compatibility/deprecations.md index 6ff124b27a34fa..62752b2c54d6f0 100644 --- a/docs/designers-developers/developers/backward-compatibility/deprecations.md +++ b/docs/designers-developers/developers/backward-compatibility/deprecations.md @@ -58,6 +58,7 @@ The Gutenberg project's deprecation policy is intended to support backward compa - The PHP function `gutenberg_collect_meta_box_data` has been removed. Use [`register_and_do_post_meta_boxes`](https://developer.wordpress.org/reference/functions/register_and_do_post_meta_boxes/) instead. - `window._wpLoadGutenbergEditor` has been removed. Use `window._wpLoadBlockEditor` instead. Note: This is a private API, not intended for public use. It may be removed in the future. - The PHP function `gutenberg_get_script_polyfill` has been removed. Use [`wp_get_script_polyfill`](https://developer.wordpress.org/reference/functions/wp_get_script_polyfill/) instead. +- The PHP function `gutenberg_add_admin_body_class` has been removed. Use the `.block-editor-page` class selector in your stylesheets if you need to scope styles to the block editor screen. ## 4.5.0 - `Dropdown.refresh()` has been deprecated as the contained `Popover` is now automatically refreshed. diff --git a/gutenberg.php b/gutenberg.php index 13f0e148b57de8..4e0cf4bbc32cde 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -220,7 +220,6 @@ function gutenberg_init( $return, $post ) { add_action( 'admin_enqueue_scripts', 'gutenberg_editor_scripts_and_styles' ); add_filter( 'screen_options_show_screen', '__return_false' ); - add_filter( 'admin_body_class', 'gutenberg_add_admin_body_class' ); /* * Remove the emoji script as it is incompatible with both React and any @@ -299,18 +298,15 @@ function gutenberg_replace_default_add_new_button() { * Adds the block-editor-page class to the body tag on the Gutenberg page. * * @since 1.5.0 + * @deprecated 5.0.0 * * @param string $classes Space separated string of classes being added to the body tag. * @return string The $classes string, with block-editor-page appended. */ function gutenberg_add_admin_body_class( $classes ) { - // gutenberg-editor-page is left for backward compatibility. - if ( current_theme_supports( 'editor-styles' ) && current_theme_supports( 'dark-editor-style' ) ) { - return "$classes block-editor-page gutenberg-editor-page is-fullscreen-mode wp-embed-responsive is-dark-theme"; - } else { - // Default to is-fullscreen-mode to avoid jumps in the UI. - return "$classes block-editor-page gutenberg-editor-page is-fullscreen-mode wp-embed-responsive"; - } + _deprecated_function( __FUNCTION__, '5.0.0' ); + + return $classes; } /** From 21c4aacd7afbdf1354bc480a1318ab73386fd9a1 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 1 Feb 2019 14:13:41 +0800 Subject: [PATCH 11/17] Fix the editor save keyboard shortcut not working in code editor view (#13159) * Fix the editor save keyboard shortcut not working in code editor view * Refactor based on code review feedback - Introduce new TextEditorGlobalShortcuts component that implements the save shortcut - Rename EditorGlobalShortcuts to VisualEditorGlobalShortcuts - Add a deprecated version of EditorGlobalShortcuts - Update CHANGELOG --- packages/edit-post/CHANGELOG.md | 3 ++ .../src/components/text-editor/index.js | 7 ++- .../src/components/visual-editor/index.js | 4 +- packages/editor/CHANGELOG.md | 7 ++- .../components/block-settings-menu/index.js | 2 +- .../save-shortcut.js | 52 +++++++++++++++++++ .../text-editor-shortcuts.js | 10 ++++ .../visual-editor-shortcuts.js} | 48 +++++++---------- packages/editor/src/components/index.js | 6 ++- 9 files changed, 103 insertions(+), 36 deletions(-) create mode 100644 packages/editor/src/components/global-keyboard-shortcuts/save-shortcut.js create mode 100644 packages/editor/src/components/global-keyboard-shortcuts/text-editor-shortcuts.js rename packages/editor/src/components/{editor-global-keyboard-shortcuts/index.js => global-keyboard-shortcuts/visual-editor-shortcuts.js} (85%) diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index ee41b7e7fb9f1e..db8c68da542295 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -4,6 +4,9 @@ * Expose the `className` property to style the `PluginSidebar` component. +### Bug Fixes + - Fix 'save' keyboard shortcut not functioning in the Code Editor. + ## 3.1.7 (2019-01-03) ## 3.1.6 (2018-12-18) diff --git a/packages/edit-post/src/components/text-editor/index.js b/packages/edit-post/src/components/text-editor/index.js index 019a19b2e518c8..882e97dd7e83c6 100644 --- a/packages/edit-post/src/components/text-editor/index.js +++ b/packages/edit-post/src/components/text-editor/index.js @@ -1,7 +1,11 @@ /** * WordPress dependencies */ -import { PostTextEditor, PostTitle } from '@wordpress/editor'; +import { + PostTextEditor, + PostTitle, + TextEditorGlobalKeyboardShortcuts, +} from '@wordpress/editor'; import { IconButton } from '@wordpress/components'; import { withDispatch, withSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; @@ -21,6 +25,7 @@ function TextEditor( { onExit, isRichEditingEnabled } ) { > { __( 'Exit Code Editor' ) } + ) }
diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 03dbcdb3f047be..a8cdc7e06f69df 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -7,7 +7,7 @@ import { PostTitle, WritingFlow, ObserveTyping, - EditorGlobalKeyboardShortcuts, + VisualEditorGlobalKeyboardShortcuts, BlockSelectionClearer, MultiSelectScrollIntoView, _BlockSettingsMenuFirstItem, @@ -23,7 +23,7 @@ import PluginBlockSettingsMenuGroup from '../block-settings-menu/plugin-block-se function VisualEditor() { return ( - + diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 30e57fd4f033fe..c5365bd4b44df9 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -1,8 +1,13 @@ ## 9.1.0 (Unreleased) -### New Feature +### New Features - Added `createCustomColorsHOC` for creating a higher order `withCustomColors` component. +- Added a new `TextEditorGlobalKeyboardShortcuts` component. + +### Deprecations + +- `EditorGlobalKeyboardShortcuts` has been deprecated in favor of `VisualEditorGlobalKeyboardShortcuts`. ### Bug Fixes diff --git a/packages/editor/src/components/block-settings-menu/index.js b/packages/editor/src/components/block-settings-menu/index.js index ec4bbd60db53f7..8436276c8f99b5 100644 --- a/packages/editor/src/components/block-settings-menu/index.js +++ b/packages/editor/src/components/block-settings-menu/index.js @@ -15,7 +15,7 @@ import { withDispatch } from '@wordpress/data'; /** * Internal dependencies */ -import { shortcuts } from '../editor-global-keyboard-shortcuts'; +import { shortcuts } from '../global-keyboard-shortcuts/visual-editor-shortcuts'; import BlockActions from '../block-actions'; import BlockModeToggle from './block-mode-toggle'; import ReusableBlockConvertButton from './reusable-block-convert-button'; diff --git a/packages/editor/src/components/global-keyboard-shortcuts/save-shortcut.js b/packages/editor/src/components/global-keyboard-shortcuts/save-shortcut.js new file mode 100644 index 00000000000000..c2a117ec6816fb --- /dev/null +++ b/packages/editor/src/components/global-keyboard-shortcuts/save-shortcut.js @@ -0,0 +1,52 @@ +/** + * WordPress dependencies + */ +import { KeyboardShortcuts } from '@wordpress/components'; +import { rawShortcut } from '@wordpress/keycodes'; +import { compose } from '@wordpress/compose'; +import { withSelect, withDispatch } from '@wordpress/data'; + +export function SaveShortcut( { onSave } ) { + return ( + { + event.preventDefault(); + onSave(); + }, + } } + /> + ); +} + +export default compose( [ + withSelect( ( select ) => { + const { isEditedPostDirty } = select( 'core/editor' ); + + return { + isDirty: isEditedPostDirty(), + }; + } ), + withDispatch( ( dispatch, ownProps, { select } ) => { + const { + savePost, + } = dispatch( 'core/editor' ); + + return { + onSave() { + // TODO: This should be handled in the `savePost` effect in + // considering `isSaveable`. See note on `isEditedPostSaveable` + // selector about dirtiness and meta-boxes. + // + // See: `isEditedPostSaveable` + const { isEditedPostDirty } = select( 'core/editor' ); + if ( ! isEditedPostDirty() ) { + return; + } + + savePost(); + }, + }; + } ), +] )( SaveShortcut ); diff --git a/packages/editor/src/components/global-keyboard-shortcuts/text-editor-shortcuts.js b/packages/editor/src/components/global-keyboard-shortcuts/text-editor-shortcuts.js new file mode 100644 index 00000000000000..2d2d0510fd3167 --- /dev/null +++ b/packages/editor/src/components/global-keyboard-shortcuts/text-editor-shortcuts.js @@ -0,0 +1,10 @@ +/** + * Internal dependencies + */ +import SaveShortcut from './save-shortcut'; + +export default function TextEditorGlobalKeyboardShortcuts() { + return ( + + ); +} diff --git a/packages/editor/src/components/editor-global-keyboard-shortcuts/index.js b/packages/editor/src/components/global-keyboard-shortcuts/visual-editor-shortcuts.js similarity index 85% rename from packages/editor/src/components/editor-global-keyboard-shortcuts/index.js rename to packages/editor/src/components/global-keyboard-shortcuts/visual-editor-shortcuts.js index ed2a4039755b1f..9242734d0e9e4a 100644 --- a/packages/editor/src/components/editor-global-keyboard-shortcuts/index.js +++ b/packages/editor/src/components/global-keyboard-shortcuts/visual-editor-shortcuts.js @@ -11,11 +11,13 @@ import { KeyboardShortcuts } from '@wordpress/components'; import { withSelect, withDispatch } from '@wordpress/data'; import { rawShortcut, displayShortcut } from '@wordpress/keycodes'; import { compose } from '@wordpress/compose'; +import deprecated from '@wordpress/deprecated'; /** * Internal dependencies */ import BlockActions from '../block-actions'; +import SaveShortcut from './save-shortcut'; const preventDefault = ( event ) => { event.preventDefault(); @@ -41,13 +43,12 @@ export const shortcuts = { }, }; -class EditorGlobalKeyboardShortcuts extends Component { +class VisualEditorGlobalKeyboardShortcuts extends Component { constructor() { super( ...arguments ); this.selectAll = this.selectAll.bind( this ); this.undoOrRedo = this.undoOrRedo.bind( this ); - this.save = this.save.bind( this ); this.deleteSelectedBlocks = this.deleteSelectedBlocks.bind( this ); this.clearMultiSelection = this.clearMultiSelection.bind( this ); } @@ -70,11 +71,6 @@ class EditorGlobalKeyboardShortcuts extends Component { event.preventDefault(); } - save( event ) { - event.preventDefault(); - this.props.onSave(); - } - deleteSelectedBlocks( event ) { const { selectedBlockClientIds, hasMultiSelection, onRemove, isLocked } = this.props; if ( hasMultiSelection ) { @@ -110,12 +106,7 @@ class EditorGlobalKeyboardShortcuts extends Component { escape: this.clearMultiSelection, } } /> - + { selectedBlockClientIds.length > 0 && ( { ( { onDuplicate, onRemove, onInsertAfter, onInsertBefore } ) => ( @@ -146,7 +137,7 @@ class EditorGlobalKeyboardShortcuts extends Component { } } -export default compose( [ +const EnhancedVisualEditorGlobalKeyboardShortcuts = compose( [ withSelect( ( select ) => { const { getBlockOrder, @@ -169,30 +160,16 @@ export default compose( [ selectedBlockClientIds, }; } ), - withDispatch( ( dispatch, ownProps, { select } ) => { + withDispatch( ( dispatch ) => { const { clearSelectedBlock, multiSelect, redo, undo, removeBlocks, - savePost, } = dispatch( 'core/editor' ); return { - onSave() { - // TODO: This should be handled in the `savePost` effect in - // considering `isSaveable`. See note on `isEditedPostSaveable` - // selector about dirtiness and meta-boxes. - // - // See: `isEditedPostSaveable` - const { isEditedPostDirty } = select( 'core/editor' ); - if ( ! isEditedPostDirty() ) { - return; - } - - savePost(); - }, clearSelectedBlock, onMultiSelect: multiSelect, onRedo: redo, @@ -200,4 +177,15 @@ export default compose( [ onRemove: removeBlocks, }; } ), -] )( EditorGlobalKeyboardShortcuts ); +] )( VisualEditorGlobalKeyboardShortcuts ); + +export default EnhancedVisualEditorGlobalKeyboardShortcuts; + +export function EditorGlobalKeyboardShortcuts() { + deprecated( 'EditorGlobalKeyboardShortcuts', { + alternative: 'VisualEditorGlobalKeyboardShortcuts', + plugin: 'Gutenberg', + } ); + + return ; +} diff --git a/packages/editor/src/components/index.js b/packages/editor/src/components/index.js index ebd0a59331198c..b02da43dbfe579 100644 --- a/packages/editor/src/components/index.js +++ b/packages/editor/src/components/index.js @@ -36,7 +36,11 @@ export { default as URLPopover } from './url-popover'; export { default as AutosaveMonitor } from './autosave-monitor'; export { default as DocumentOutline } from './document-outline'; export { default as DocumentOutlineCheck } from './document-outline/check'; -export { default as EditorGlobalKeyboardShortcuts } from './editor-global-keyboard-shortcuts'; +export { + default as VisualEditorGlobalKeyboardShortcuts, + EditorGlobalKeyboardShortcuts, +} from './global-keyboard-shortcuts/visual-editor-shortcuts'; +export { default as TextEditorGlobalKeyboardShortcuts } from './global-keyboard-shortcuts/text-editor-shortcuts'; export { default as EditorHistoryRedo } from './editor-history/redo'; export { default as EditorHistoryUndo } from './editor-history/undo'; export { default as EditorNotices } from './editor-notices'; From 2009bdd34d4fee4592b8c460615aca420bebdd3b Mon Sep 17 00:00:00 2001 From: Kjell Reigstad Date: Fri, 1 Feb 2019 03:14:21 -0500 Subject: [PATCH 12/17] Increase bottom padding on gallery image caption (#13623) Resolves #8018 by increasing the bottom padding of gallery image captions by 4px. Also increases the coverage of our gradient background by 10% to help with text contrast. --- packages/block-library/src/gallery/style.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index a62465bb4f225f..2557f727c5c0e9 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -48,11 +48,11 @@ width: 100%; max-height: 100%; overflow: auto; - padding: 40px 10px 5px; + padding: 40px 10px 9px; color: $white; text-align: center; font-size: $default-font-size; - background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 60%, transparent); + background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); img { display: inline; From dfc970d8a1299993bc47e4a75b5a18779b2f2072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20Van=C2=A0Durpe?= Date: Fri, 1 Feb 2019 09:58:15 +0100 Subject: [PATCH 13/17] Fix Google Docs table paste (#13543) --- .../raw-handling/phrasing-content-reducer.js | 21 ++----------------- .../test/phrasing-content-reducer.js | 4 ---- .../blocks/src/api/raw-handling/test/utils.js | 6 ++++++ packages/blocks/src/api/raw-handling/utils.js | 16 ++++++++++++-- test/integration/blocks-raw-handling.spec.js | 1 + .../fixtures/google-docs-table-in.html | 1 + .../fixtures/google-docs-table-out.html | 3 +++ 7 files changed, 27 insertions(+), 25 deletions(-) create mode 100644 test/integration/fixtures/google-docs-table-in.html create mode 100644 test/integration/fixtures/google-docs-table-out.html diff --git a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js index 3bc6fa11fb2396..5237c28495ee79 100644 --- a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js +++ b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js @@ -1,18 +1,9 @@ /** * WordPress dependencies */ -import { wrap, unwrap, replaceTag } from '@wordpress/dom'; +import { wrap, replaceTag } from '@wordpress/dom'; -/** - * Internal dependencies - */ -import { isPhrasingContent } from './phrasing-content'; - -function isBlockContent( node, schema = {} ) { - return schema.hasOwnProperty( node.nodeName.toLowerCase() ); -} - -export default function( node, doc, schema ) { +export default function( node, doc ) { if ( node.nodeName === 'SPAN' ) { const { fontWeight, @@ -50,12 +41,4 @@ export default function( node, doc, schema ) { node.removeAttribute( 'rel' ); } } - - if ( - isPhrasingContent( node ) && - node.hasChildNodes() && - Array.from( node.childNodes ).some( ( child ) => isBlockContent( child, schema ) ) - ) { - unwrap( node ); - } } diff --git a/packages/blocks/src/api/raw-handling/test/phrasing-content-reducer.js b/packages/blocks/src/api/raw-handling/test/phrasing-content-reducer.js index 254344e50b11d3..14a9d26984956b 100644 --- a/packages/blocks/src/api/raw-handling/test/phrasing-content-reducer.js +++ b/packages/blocks/src/api/raw-handling/test/phrasing-content-reducer.js @@ -21,10 +21,6 @@ describe( 'phrasingContentReducer', () => { expect( deepFilterHTML( 'test', [ phrasingContentReducer ], {} ) ).toEqual( 'test' ); } ); - it( 'should remove invalid phrasing content', () => { - expect( deepFilterHTML( '

test

', [ phrasingContentReducer ], { p: {} } ) ).toEqual( '

test

' ); - } ); - it( 'should normalise the rel attribute', () => { const input = 'WordPress'; const output = 'WordPress'; diff --git a/packages/blocks/src/api/raw-handling/test/utils.js b/packages/blocks/src/api/raw-handling/test/utils.js index 66b0e8ffd0a5e0..efaea872497ae9 100644 --- a/packages/blocks/src/api/raw-handling/test/utils.js +++ b/packages/blocks/src/api/raw-handling/test/utils.js @@ -186,6 +186,12 @@ describe( 'removeInvalidHTML', () => { const output = '

test

test'; expect( removeInvalidHTML( input, schema ) ).toBe( output ); } ); + + it( 'should remove invalid phrasing content', () => { + const input = '

test

'; + const output = '

test

'; + expect( removeInvalidHTML( input, schema ) ).toEqual( output ); + } ); } ); describe( 'getBlockContentSchema', () => { diff --git a/packages/blocks/src/api/raw-handling/utils.js b/packages/blocks/src/api/raw-handling/utils.js index 82f0903824a762..d917b681f94568 100644 --- a/packages/blocks/src/api/raw-handling/utils.js +++ b/packages/blocks/src/api/raw-handling/utils.js @@ -239,9 +239,21 @@ function cleanNodeList( nodeList, doc, schema, inline ) { if ( require.length && ! node.querySelector( require.join( ',' ) ) ) { cleanNodeList( node.childNodes, doc, schema, inline ); unwrap( node ); - } + // If the node is at the top, phrasing content, and + // contains children that are block content, unwrap + // the node because it is invalid. + } else if ( + node.parentNode.nodeName === 'BODY' && + isPhrasingContent( node ) + ) { + cleanNodeList( node.childNodes, doc, schema, inline ); - cleanNodeList( node.childNodes, doc, children, inline ); + if ( Array.from( node.childNodes ).some( ( child ) => ! isPhrasingContent( child ) ) ) { + unwrap( node ); + } + } else { + cleanNodeList( node.childNodes, doc, children, inline ); + } // Remove children if the node is not supposed to have any. } else { while ( node.firstChild ) { diff --git a/test/integration/blocks-raw-handling.spec.js b/test/integration/blocks-raw-handling.spec.js index 364658b1ebf9fa..4e0b6c4d60b706 100644 --- a/test/integration/blocks-raw-handling.spec.js +++ b/test/integration/blocks-raw-handling.spec.js @@ -207,6 +207,7 @@ describe( 'Blocks raw handling', () => { 'classic', 'apple', 'google-docs', + 'google-docs-table', 'ms-word', 'ms-word-styled', 'ms-word-online', diff --git a/test/integration/fixtures/google-docs-table-in.html b/test/integration/fixtures/google-docs-table-in.html new file mode 100644 index 00000000000000..8a6b117fa6ed55 --- /dev/null +++ b/test/integration/fixtures/google-docs-table-in.html @@ -0,0 +1 @@ +

One

Two

Three

1

2

3

I

II

III

diff --git a/test/integration/fixtures/google-docs-table-out.html b/test/integration/fixtures/google-docs-table-out.html new file mode 100644 index 00000000000000..697c2d41ea5cd9 --- /dev/null +++ b/test/integration/fixtures/google-docs-table-out.html @@ -0,0 +1,3 @@ + +
OneTwoThree
123
IIIIII
+ From ba673eb0b6f38dc611211640eec94c89c7cc6866 Mon Sep 17 00:00:00 2001 From: "Nahid F. Mohit" Date: Fri, 1 Feb 2019 01:04:58 -0800 Subject: [PATCH 14/17] Introduce left and right float alignment options to latest posts block (#8814) --- packages/block-library/src/latest-posts/edit.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/block-library/src/latest-posts/edit.js b/packages/block-library/src/latest-posts/edit.js index 650d257603e18d..f6bc6953f2955a 100644 --- a/packages/block-library/src/latest-posts/edit.js +++ b/packages/block-library/src/latest-posts/edit.js @@ -161,7 +161,6 @@ class LatestPostsEdit extends Component { onChange={ ( nextAlign ) => { setAttributes( { align: nextAlign } ); } } - controls={ [ 'center', 'wide', 'full' ] } /> From 9fbab73ca4b37fd1aeabe7ce46cf25a563e6b422 Mon Sep 17 00:00:00 2001 From: Marty Helmick Date: Fri, 1 Feb 2019 04:46:57 -0500 Subject: [PATCH 15/17] Remove unintentional right-margin on last odd-item. (#12199) * Remove unintentional right-margin on last odd-item. Looks like it wasn't intended to for the last column to have a `right-margin`, but the `:not(:last-child)` used here would only "not add" the margin. It didn't remove it if the column was odd numbered. This simplifies the logic and adds right and left margin to all columns but removes it from first-left and last-right. I also replaced the `flex: 1;` property with `flex-grow: 1;`. `flex: 1` is = to `flex-grow: 1; flex-shrink: 1; flex-basis: 0;` In this case `flex-shrink` keeps it's default value of `1` and `flex-basis` overwritten and is set to `100%` a couple lines after. So `flex-grow` is all we need. * update editor to match style.css column margin changes * account for beginning and end margins with breakpoints * update editor.css to match style.css * account for editor block padding and the medium breakpoint * remove whitespace * account for negative margins added by the editor * correct flex-basis calculation for column width --- .../block-library/src/columns/editor.scss | 18 ++++-------- packages/block-library/src/columns/style.scss | 28 ++++++++----------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/packages/block-library/src/columns/editor.scss b/packages/block-library/src/columns/editor.scss index ebd2cbf5fdb9d7..cadafcd2ef360b 100644 --- a/packages/block-library/src/columns/editor.scss +++ b/packages/block-library/src/columns/editor.scss @@ -35,7 +35,7 @@ // Responsiveness: Allow wrapping on mobile. flex-wrap: wrap; - @include break-small() { + @include break-medium() { flex-wrap: nowrap; } @@ -89,7 +89,7 @@ // Beyond mobile, allow 2 columns. @include break-small() { - flex-basis: 50%; + flex-basis: calc(50% - (#{$grid-size-large} + #{$block-padding * 2})); flex-grow: 0; } @@ -97,21 +97,15 @@ // This has to match the same padding applied in style.scss. // Only apply this beyond the mobile breakpoint, as there's only a single column on mobile. @include break-small() { - &:nth-child(odd) { - margin-right: $grid-size-large * 2; - } &:nth-child(even) { - margin-left: $grid-size-large * 2; + margin-left: calc(#{$grid-size-large * 2} + #{$block-padding}); } } - @include break-small() { + // When columns are in a single row, add space before all except the first. + @include break-medium() { &:not(:first-child) { - margin-left: $grid-size-large * 2; - } - - &:not(:last-child) { - margin-right: $grid-size-large * 2; + margin-left: calc(#{$grid-size-large * 2} + #{$block-padding}); } } } diff --git a/packages/block-library/src/columns/style.scss b/packages/block-library/src/columns/style.scss index 90c61ea5acb0ff..00322b0afe7997 100644 --- a/packages/block-library/src/columns/style.scss +++ b/packages/block-library/src/columns/style.scss @@ -10,18 +10,12 @@ } .wp-block-column { - flex: 1; + flex-grow: 1; margin-bottom: 1em; // Responsiveness: Show at most one columns on mobile. flex-basis: 100%; - // Beyond mobile, allow 2 columns. - @include break-small() { - flex-basis: 50%; - flex-grow: 0; - } - // Prevent the columns from growing wider than their distributed sizes. min-width: 0; @@ -29,22 +23,24 @@ word-break: break-word; // For back-compat. overflow-wrap: break-word; // New standard. - // Add space between columns. Themes can customize this if they wish to work differently. - // Only apply this beyond the mobile breakpoint, as there's only a single column on mobile. @include break-small() { - &:nth-child(odd) { - margin-right: $grid-size-large * 2; - } + + // Beyond mobile, allow 2 columns. + flex-basis: calc(50% - #{$grid-size-large}); + flex-grow: 0; + + // Add space between the 2 columns. Themes can customize this if they wish to work differently. + // Only apply this beyond the mobile breakpoint, as there's only a single column on mobile. &:nth-child(even) { margin-left: $grid-size-large * 2; } + } + + @include break-medium() { + // When columns are in a single row, add space before all except the first. &:not(:first-child) { margin-left: $grid-size-large * 2; } - - &:not(:last-child) { - margin-right: $grid-size-large * 2; - } } } From c20a644d5247a3adc24635b9145174be20bb1faf Mon Sep 17 00:00:00 2001 From: etoledom Date: Fri, 1 Feb 2019 10:48:35 +0100 Subject: [PATCH 16/17] Mobile bottom sheet component (#13612) * rnmobile: Implement image settings button using InspectorControls.Slot pattern. * rnmobile: Add missing semicolon * rnmobile: Adding bottom-sheet component to mobile * rnmobile: Styling bottom-sheet header * rnmobile: Bottom-sheet clean up * rnmobile: Fix lint issues on bottom-sheet related code. * rnmobile: Fix small lint issues * rnmobile: Move inline toolbar button definition out of constant. * rnmobile: Remove extra white-spaces * revert package-lock.json changes * rnmobile: Fix merge issue * rnmobile: exporting component BottomSheet.Button to be used as bottom-sheet header buttons * rnmobile: Adding BottomSheet.Cell component as an extraction for BottomSheet users. * Fix lint issues * Reverting changes to package-lock.json * Fix merge issues --- .../block-library/src/image/edit.native.js | 35 ++++++-- .../editor/src/components/index.native.js | 1 + .../mobile/bottom-sheet/button.native.js | 32 +++++++ .../mobile/bottom-sheet/cell.native.js | 24 +++++ .../mobile/bottom-sheet/index.native.js | 90 +++++++++++++++++++ .../mobile/bottom-sheet/styles.scss | 82 +++++++++++++++++ 6 files changed, 256 insertions(+), 8 deletions(-) create mode 100644 packages/editor/src/components/mobile/bottom-sheet/button.native.js create mode 100644 packages/editor/src/components/mobile/bottom-sheet/cell.native.js create mode 100644 packages/editor/src/components/mobile/bottom-sheet/index.native.js create mode 100644 packages/editor/src/components/mobile/bottom-sheet/styles.scss diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index fe3fa7c54d2e15..8ab944d274fe53 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -16,7 +16,7 @@ import { /** * Internal dependencies */ -import { MediaPlaceholder, RichText, BlockControls, InspectorControls } from '@wordpress/editor'; +import { MediaPlaceholder, RichText, BlockControls, InspectorControls, BottomSheet } from '@wordpress/editor'; import { Toolbar, ToolbarButton, Spinner, Dashicon } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import ImageSize from './image-size'; @@ -33,6 +33,7 @@ export default class ImageEdit extends React.Component { super( props ); this.state = { + showSettings: false, progress: 0, isUploadInProgress: false, isUploadFailed: false, @@ -168,7 +169,11 @@ export default class ImageEdit extends React.Component { } const onImageSettingsButtonPressed = () => { + this.setState( { showSettings: true } ); + }; + const onImageSettingsClose = () => { + this.setState( { showSettings: false } ); }; const toolbarEditButton = ( @@ -181,12 +186,21 @@ export default class ImageEdit extends React.Component { ); - const inlineToolbarButtons = ( - + const getInspectorControls = () => ( + + } + > + {} } /> + ); const showSpinner = this.state.isUploadInProgress; @@ -201,7 +215,11 @@ export default class ImageEdit extends React.Component { { toolbarEditButton } - { inlineToolbarButtons } + { ( sizes ) => { @@ -222,6 +240,7 @@ export default class ImageEdit extends React.Component { return ( + { getInspectorControls() } + + + { text } + + + + ); +} diff --git a/packages/editor/src/components/mobile/bottom-sheet/cell.native.js b/packages/editor/src/components/mobile/bottom-sheet/cell.native.js new file mode 100644 index 00000000000000..7ad3a2db4b6933 --- /dev/null +++ b/packages/editor/src/components/mobile/bottom-sheet/cell.native.js @@ -0,0 +1,24 @@ +/** +* External dependencies +*/ +import { TouchableOpacity, Text } from 'react-native'; + +/** + * Internal dependencies + */ +import styles from './styles.scss'; + +export default function Cell( props ) { + const { + onPress, + label, + value, + } = props; + + return ( + + { label } + { value } + + ); +} diff --git a/packages/editor/src/components/mobile/bottom-sheet/index.native.js b/packages/editor/src/components/mobile/bottom-sheet/index.native.js new file mode 100644 index 00000000000000..781eb01337e4c2 --- /dev/null +++ b/packages/editor/src/components/mobile/bottom-sheet/index.native.js @@ -0,0 +1,90 @@ +/** + * External dependencies + */ +import { Text, View } from 'react-native'; +import Modal from 'react-native-modal'; +import SafeArea from 'react-native-safe-area'; + +/** + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import styles from './styles.scss'; +import Button from './button'; +import Cell from './cell'; + +class BottomSheet extends Component { + constructor() { + super( ...arguments ); + this.onSafeAreaInsetsUpdate = this.onSafeAreaInsetsUpdate.bind( this ); + this.state = { + safeAreaBottomInset: 0, + }; + + SafeArea.getSafeAreaInsetsForRootView().then( this.onSafeAreaInsetsUpdate ); + } + + componentDidMount() { + SafeArea.addEventListener( 'safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsUpdate ); + } + + componentWillUnmount() { + SafeArea.removeEventListener( 'safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsUpdate ); + } + + onSafeAreaInsetsUpdate( result ) { + const { safeAreaInsets } = result; + if ( this.state.safeAreaBottomInset !== safeAreaInsets.bottom ) { + this.setState( { safeAreaBottomInset: safeAreaInsets.bottom } ); + } + } + + render() { + const { isVisible, leftButton, rightButton } = this.props; + + return ( + + + + + + { leftButton } + + + + { this.props.title } + + + + { rightButton } + + + + + { this.props.children } + + + + + ); + } +} + +BottomSheet.Button = Button; +BottomSheet.Cell = Cell; + +export default BottomSheet; diff --git a/packages/editor/src/components/mobile/bottom-sheet/styles.scss b/packages/editor/src/components/mobile/bottom-sheet/styles.scss new file mode 100644 index 00000000000000..1062ebceaa8e32 --- /dev/null +++ b/packages/editor/src/components/mobile/bottom-sheet/styles.scss @@ -0,0 +1,82 @@ +//Bottom Sheet + +.bottomModal { + justify-content: flex-end; + margin: 0; +} + +.dragIndicator { + background-color: $light-gray-400; + height: 4px; + width: 10%; + top: -12px; + margin: auto; + border-radius: 2px; +} + +.separator { + background-color: $light-gray-400; + height: 1px; + width: 100%; + margin: auto; +} + +.content { + background-color: $white; + padding: 18px 10px 5px 10px; + justify-content: center; + border-top-right-radius: 8px; + border-top-left-radius: 8px; +} + +.head { + flex-direction: row; + width: 100%; + margin-bottom: 5px; + justify-content: space-between; + align-items: center; + align-content: center; +} + +.title { + color: $dark-gray-600; + font-size: 18px; + font-weight: 600; + text-align: center; +} + +.titleContainer { + justify-content: center; + flex: 2; + align-content: center; +} + +// Button + +.buttonText { + font-size: 18px; + padding: 5px; +} + +// Cell + +//Bottom Sheet + +.cellContainer { + flex-direction: row; + min-height: 50; + justify-content: space-between; + padding-left: 12; + padding-right: 12; + align-items: center; +} + +.cellLabel { + font-size: 18px; + color: #000; +} + +.cellValue { + font-size: 18px; + color: $dark-gray-400; +} From 532ed5fcc9e96400be28cf74ccc405ce4e6a39dd Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Fri, 1 Feb 2019 11:17:30 +0100 Subject: [PATCH 17/17] Try alternate list item jump fix. (#12941) * Try alternate list item jump fix. This PR is an alternative to #12590, and also fixes #12526. Props @Naerriel for initial work and inspiration. The different approach taken here is to embrace that we are applying a specific margin to our list items and overrides bleed from wp-admin. In doing so it moves these margins to the editor styles stylesheet, which is a more appropriate place for it. * Move to "initial". --- packages/editor/src/editor-styles.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/editor/src/editor-styles.scss b/packages/editor/src/editor-styles.scss index e9d58922c13ca3..6715bd4d0c9877 100644 --- a/packages/editor/src/editor-styles.scss +++ b/packages/editor/src/editor-styles.scss @@ -14,6 +14,11 @@ ul, ol { margin: 0; padding: 0; + + li { + // This overrides a bottom margin globally applied to list items in wp-admin. + margin-bottom: initial; + } } ul {