From 5c56d8eb173009d294cc4afb31591dcbcee6d1fe Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Fri, 12 Oct 2018 16:30:36 +0100 Subject: [PATCH 01/27] docs: Add gutenberg-js logo --- README.md | 2 ++ gutenberg_js_logo.svg | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 gutenberg_js_logo.svg diff --git a/README.md b/README.md index 72bd0dc..81705b2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # gutenberg-js +![gutenberg-js](gutenberg_js_logo.svg?raw=true "gutenberg-js") + We made [Gutenberg](https://github.com/Wordpress/gutenberg) editor a little more **customizable**! Gutenberg editor can **be easly included in your apps** with this [package](https://github.com/front/gutenberg-js). Also you can customize blocks menu panels, blocks categories, document panels and more! diff --git a/gutenberg_js_logo.svg b/gutenberg_js_logo.svg new file mode 100644 index 0000000..2ecedc8 --- /dev/null +++ b/gutenberg_js_logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + From 36d896805a51d7fb77cda7fe8f939f583fde77db Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Fri, 12 Oct 2018 16:35:31 +0100 Subject: [PATCH 02/27] docs: Fix g-js logo in readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 81705b2..b79d5c7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # gutenberg-js -![gutenberg-js](gutenberg_js_logo.svg?raw=true "gutenberg-js") +![gutenberg-js](gutenberg_js_logo.svg?sanitize=true "gutenberg-js") + We made [Gutenberg](https://github.com/Wordpress/gutenberg) editor a little more **customizable**! From 1365b35e0782b04719fe01b400e229215df469a1 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Fri, 12 Oct 2018 16:36:12 +0100 Subject: [PATCH 03/27] docs: Remove logo duplicate --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index b79d5c7..296963f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # gutenberg-js ![gutenberg-js](gutenberg_js_logo.svg?sanitize=true "gutenberg-js") - We made [Gutenberg](https://github.com/Wordpress/gutenberg) editor a little more **customizable**! From 775e8bf4d66a59f93f375f827808623f460fb115 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 10:34:17 +0100 Subject: [PATCH 04/27] chore: Add react version to eslint config --- .eslintrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index bea2b9f..5ae954e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -29,7 +29,8 @@ ], "settings": { "react": { - "pragma": "React" + "pragma": "React", + "version": "16.0" } }, "rules": { From bc720865e219b21178a7ef78fc67098e547bd802 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 10:37:46 +0100 Subject: [PATCH 05/27] chore: Update install script --- scripts/install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 0af6f88..75c0348 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -13,10 +13,11 @@ git clone https://github.com/WordPress/gutenberg.git cd gutenberg # checkout to version we want -git checkout tags/v3.9.0 +git checkout tags/v4.0.0 # remove git references -rm -rf .git +# GUTENBERG HAS A SUBMODULE NOW +# rm -rf .git # install gutenberg dependencies npm i From b29adb2bf4b25ac9622bb1f339f7eead8fa99066 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 10:43:54 +0100 Subject: [PATCH 06/27] chore: Add deploy script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 1fe3d03..d48b06d 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "dev": "NODE_ENV=development webpack", "lint": "eslint .", "lint:fix": "eslint . --fix", - "postinstall": "./scripts/install.sh" + "postinstall": "./scripts/install.sh", + "deploy": "npm run lint && npm publish --access public" }, "homepage": "https://github.com/front/gutenberg-js#readme", "bugs": { From 84fb72405b293eefbced82989172aa7424c55c62 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 10:44:56 +0100 Subject: [PATCH 07/27] chore: Add missing package to webpack config and update it according gutenberg 4.0 --- webpack.config.js | 49 +++++++++-------------------------------------- 1 file changed, 9 insertions(+), 40 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index 77bc36e..b73ec1b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -28,21 +28,6 @@ const mainCSSExtractTextPlugin = new ExtractTextPlugin({ filename: './css/style.css', }); -// CSS loader for styles specific to block editing. -const editBlocksCSSPlugin = new ExtractTextPlugin({ - filename: './css/block-library/edit-blocks.css', -}); - -// CSS loader for styles specific to blocks in general. -const blocksCSSPlugin = new ExtractTextPlugin({ - filename: './css/block-library/style.css', -}); - -// CSS loader for default visual block styles. -const themeBlocksCSSPlugin = new ExtractTextPlugin({ - filename: './css/block-library/theme.css', -}); - // Configuration for the ExtractTextPlugin. const extractConfig = { use: [ @@ -56,7 +41,7 @@ const extractConfig = { { loader: 'sass-loader', query: { - includePaths: [ './node_modules/gutenberg/edit-post/assets/stylesheets' ], + includePaths: [ './node_modules/gutenberg/assets/stylesheets' ], data: '@import "colors"; @import "breakpoints"; @import "variables"; @import "mixins"; @import "animations"; @import "z-index";', outputStyle: 'production' === process.env.NODE_ENV ? 'compressed' : 'nested', @@ -84,16 +69,16 @@ function camelCaseDash (string) { const entryPointNames = [ 'components', - 'edit-post', - 'block-library', + // 'block-library', ]; const gutenbergPackages = [ 'a11y', + // 'api-fetch', // global 'autop', 'blob', 'blocks', - 'block-library', // keep it here because package overrides + 'block-library', 'block-serialization-default-parser', 'block-serialization-spec-parser', 'browserslist-config', @@ -105,8 +90,10 @@ const gutenbergPackages = [ 'deprecated', 'dom', 'dom-ready', + 'edit-post', 'editor', 'element', + 'escape-html', 'hooks', 'html-entities', 'i18n', @@ -116,8 +103,10 @@ const gutenbergPackages = [ 'nux', 'plugins', 'redux-routine', + 'rich-text', 'shortcode', 'token-list', + // 'url', // global 'viewport', 'wordcount', ]; @@ -191,19 +180,12 @@ const config = { }, ], }, - { - test: /style\.s?css$/, - include: [ - /block-library/, - ], - use: blocksCSSPlugin.extract(extractConfig), - }, { test: /editor\.s?css$/, include: [ /block-library/, ], - use: editBlocksCSSPlugin.extract({ + use: mainCSSExtractTextPlugin.extract({ use: [ { // removing .gutenberg class in editor.scss files @@ -219,26 +201,13 @@ const config = { ], }), }, - { - test: /theme\.s?css$/, - include: [ - /block-library/, - ], - use: themeBlocksCSSPlugin.extract(extractConfig), - }, { test: /\.s?css$/, - exclude: [ - /block-library/, - ], use: mainCSSExtractTextPlugin.extract(extractConfig), }, ], }, plugins: [ - blocksCSSPlugin, - editBlocksCSSPlugin, - themeBlocksCSSPlugin, mainCSSExtractTextPlugin, // wrapping editor style with .gutenberg__editor class // new PostCssWrapper('./css/block-library/edit-blocks.css', '.gutenberg__editor'), From cf9f195d0be04f7e6a19b5f4161a7395cd1b6b0d Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 11:01:59 +0100 Subject: [PATCH 08/27] feat: Add addQueryArgs to 'Manage All Reusable Blocks' links --- .../components/header/more-menu/index.js | 62 ------------------- .../packages/edit-post/CHANGELOG.md | 7 +++ .../edit-post/build-module/plugins/index.js | 42 +++++++++++++ .../packages/editor/CHANGELOG.md | 6 ++ .../build-module/components/inserter/menu.js | 11 ++-- 5 files changed, 61 insertions(+), 67 deletions(-) delete mode 100644 src/js/gutenberg-overrides/edit-post/components/header/more-menu/index.js create mode 100644 src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md create mode 100644 src/js/gutenberg-overrides/packages/edit-post/build-module/plugins/index.js diff --git a/src/js/gutenberg-overrides/edit-post/components/header/more-menu/index.js b/src/js/gutenberg-overrides/edit-post/components/header/more-menu/index.js deleted file mode 100644 index a23bbe6..0000000 --- a/src/js/gutenberg-overrides/edit-post/components/header/more-menu/index.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * External Dependencies - */ -import React from 'react'; - -/** - * WordPress dependencies - */ -import { __, _x } from '@wordpress/i18n'; -import { IconButton, Dropdown, MenuGroup, MenuItem } from '@wordpress/components'; -import { Fragment } from '@wordpress/element'; -// GUTENBERG JS - use addQueryArgs instead of hard coding -// 'edit.php?post_type=wp_block' -import { addQueryArgs } from '@wordpress/url'; - -/** - * Internal dependencies - */ -import './style.scss'; -import ModeSwitcher from '../mode-switcher'; -import PluginMoreMenuGroup from '../plugins-more-menu-group'; -import TipsToggle from '../tips-toggle'; -import KeyboardShortcutsHelpMenuItem from '../keyboard-shortcuts-help-menu-item'; -import WritingMenu from '../writing-menu'; - -const MoreMenu = () => ( - ( - - ) } - renderContent={ ({ onClose }) => ( - - - - - - - { __('Manage All Reusable Blocks') } - - - - - - ) } - /> -); - -export default MoreMenu; diff --git a/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md b/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md new file mode 100644 index 0000000..27ada71 --- /dev/null +++ b/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md @@ -0,0 +1,7 @@ +# edit-post changelog + +## 2.7.0 2018-10-25 + +### Added + +- `addQueryArgs` to 'Manage All Reusable Blocks' link (ToolsMoreMenuGroup) ([packages/edit-post/build-module/plugins/index.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/edit-post/build-module/plugins/index.js)) diff --git a/src/js/gutenberg-overrides/packages/edit-post/build-module/plugins/index.js b/src/js/gutenberg-overrides/packages/edit-post/build-module/plugins/index.js new file mode 100644 index 0000000..66c78ce --- /dev/null +++ b/src/js/gutenberg-overrides/packages/edit-post/build-module/plugins/index.js @@ -0,0 +1,42 @@ +/** + * WordPress dependencies + */ +import React from 'react'; +import { MenuItem } from '@wordpress/components'; +import { Fragment } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { registerPlugin } from '@wordpress/plugins'; + +// GUTENBERG JS - use addQueryArgs instead of hard coding +// 'edit.php?post_type=wp_block' +import { addQueryArgs } from '@wordpress/url'; + +/** + * Internal dependencies + */ +import CopyContentMenuItem from './copy-content-menu-item'; +import KeyboardShortcutsHelpMenuItem from './keyboard-shortcuts-help-menu-item'; +import ToolsMoreMenuGroup from '../components/header/tools-more-menu-group'; + +registerPlugin('edit-post', { + render () { + return ( + + + { ({ onClose }) => ( + + + { __('Manage All Reusable Blocks') } + + + + + ) } + + + ); + }, +}); diff --git a/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md b/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md index 53e3195..751bdad 100644 --- a/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md @@ -1,5 +1,11 @@ # editor changelog +## 2.7.0 2018-10-25 + +### Added + +- `addQueryArgs` to 'Manage All Reusable Blocks' link (Inserter Menu) ([packages/editor/build-module/components/inserter/menu.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/editor/build-module/components/inserter/menu.js)) + ## 2.5.0 2018-09-19 ### Changed diff --git a/src/js/gutenberg-overrides/packages/editor/build-module/components/inserter/menu.js b/src/js/gutenberg-overrides/packages/editor/build-module/components/inserter/menu.js index 8da9bb7..e6c787a 100644 --- a/src/js/gutenberg-overrides/packages/editor/build-module/components/inserter/menu.js +++ b/src/js/gutenberg-overrides/packages/editor/build-module/components/inserter/menu.js @@ -23,10 +23,11 @@ import scrollIntoView from 'dom-scroll-into-view'; */ import { __ } from '@wordpress/i18n'; import { Component, findDOMNode, createRef } from '@wordpress/element'; -import { withSpokenMessages, PanelBody, IconButton } from '@wordpress/components'; +import { withSpokenMessages, PanelBody } from '@wordpress/components'; import { getCategories, isReusableBlock } from '@wordpress/blocks'; import { withDispatch, withSelect } from '@wordpress/data'; import { withInstanceId, compose, withSafeTimeout } from '@wordpress/compose'; + // GUTENBERG JS - use addQueryArgs instead of hard coding // 'edit.php?post_type=wp_block' import { addQueryArgs } from '@wordpress/url'; @@ -294,12 +295,12 @@ export class InserterMenu extends Component { ref={ this.bindPanel('reusable') } > - + > + { __('Manage All Reusable Blocks') } + ) } { isEmpty(suggestedItems) && isEmpty(reusableItems) && isEmpty(itemsPerCategory) && ( From 3ed383c65a3941130d1a85d870e466c64c48168a Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 11:24:46 +0100 Subject: [PATCH 09/27] feat: Move effects override to packages/edit-post --- src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md | 4 ++++ .../edit-post/build-module}/store/effects.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) rename src/js/gutenberg-overrides/{edit-post => packages/edit-post/build-module}/store/effects.js (72%) diff --git a/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md b/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md index 27ada71..ec146d9 100644 --- a/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md @@ -4,4 +4,8 @@ ### Added +- [packages/edit-post](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/edit-post) overrides + - `addQueryArgs` to 'Manage All Reusable Blocks' link (ToolsMoreMenuGroup) ([packages/edit-post/build-module/plugins/index.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/edit-post/build-module/plugins/index.js)) + +- `OPEN_GENERAL_SIDEBAR` and `CLOSE_GENERAL_SIDEBAR` effects [packages/edit-post/build-module/store/effects.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/packages/edit-post/build-module/store/effects.js)) diff --git a/src/js/gutenberg-overrides/edit-post/store/effects.js b/src/js/gutenberg-overrides/packages/edit-post/build-module/store/effects.js similarity index 72% rename from src/js/gutenberg-overrides/edit-post/store/effects.js rename to src/js/gutenberg-overrides/packages/edit-post/build-module/store/effects.js index 5e5c8c2..3cba2e5 100644 --- a/src/js/gutenberg-overrides/edit-post/store/effects.js +++ b/src/js/gutenberg-overrides/packages/edit-post/build-module/store/effects.js @@ -2,7 +2,7 @@ * External dependencies */ import { get } from 'lodash'; -import def from 'gutenberg/edit-post/store/effects?source=node_modules'; +import def from 'gutenberg/packages/edit-post/build-module/store/effects?source=node_modules'; def.OPEN_GENERAL_SIDEBAR = (action, store) => { if (get(window, [ 'customGutenberg', 'events', 'OPEN_GENERAL_SIDEBAR' ])) { @@ -17,4 +17,4 @@ def.CLOSE_GENERAL_SIDEBAR = (action, store) => { }; export default def; -export * from 'gutenberg/edit-post/store/effects?source=node_modules'; +export * from 'gutenberg/packages/edit-post/build-module/store/effects?source=node_modules'; From 3fdbdf65adf139f3d9299fb48e286ce694fb34e7 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 11:28:03 +0100 Subject: [PATCH 10/27] feat: Move media-upload to packages/edit-post --- .../packages/edit-post/CHANGELOG.md | 4 + .../hooks/components/media-upload/index.js | 105 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/js/gutenberg-overrides/packages/edit-post/build-module/hooks/components/media-upload/index.js diff --git a/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md b/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md index ec146d9..660482b 100644 --- a/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/edit-post/CHANGELOG.md @@ -9,3 +9,7 @@ - `addQueryArgs` to 'Manage All Reusable Blocks' link (ToolsMoreMenuGroup) ([packages/edit-post/build-module/plugins/index.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/edit-post/build-module/plugins/index.js)) - `OPEN_GENERAL_SIDEBAR` and `CLOSE_GENERAL_SIDEBAR` effects [packages/edit-post/build-module/store/effects.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/packages/edit-post/build-module/store/effects.js)) + +### Changed + +- **MediaUpload** component and implement the Media Library with existing images [packages/edit-post/build-module/hooks/components/media-upload/index.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/edit-post/build-module/hooks/components/media-upload/index.js)) diff --git a/src/js/gutenberg-overrides/packages/edit-post/build-module/hooks/components/media-upload/index.js b/src/js/gutenberg-overrides/packages/edit-post/build-module/hooks/components/media-upload/index.js new file mode 100644 index 0000000..c7c570e --- /dev/null +++ b/src/js/gutenberg-overrides/packages/edit-post/build-module/hooks/components/media-upload/index.js @@ -0,0 +1,105 @@ +/** + * External dependencies + */ +import React, { Component, Fragment } from 'react'; +import { get } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Popover } from '@wordpress/components'; +import { withSelect } from '@wordpress/data'; + +class MediaContainer extends Component { + constructor (props) { + super(props); + + this.onImageClick = this.onImageClick.bind(this); + } + + onImageClick (img) { + const { onSelect, closePopover, gallery = false, multiple = false } = this.props; + + if (gallery || multiple) { + onSelect([{ ...img, url: img.source_url }]); + } + else { + onSelect({ ...img, url: img.source_url }); + } + + closePopover(); + } + + render () { + const { images } = this.props; + + return ( +
+ { images && images.map(img => { + const source_url = get(img, 'media_details.sizes.thumbnail.source_url', img.source_url); + return ; + }) } +
+ ); + } +} + +const MediaLibrary = withSelect(select => ({ + images: select('core').getMediaItems(), +}))(MediaContainer); + +class MediaUpload extends Component { + constructor (props) { + super(props); + this.state = { isVisible: false }; + + this.openPopover = this.openPopover.bind(this); + this.closePopover = this.closePopover.bind(this); + } + + openPopover () { + this.setState({ isVisible: true }); + } + + closePopover () { + this.setState({ isVisible: false }); + } + + render () { + if (!this.props.mediaLibrary) { + // console.log('Media Library is deactivated'); + return false; + } + + + const { isVisible } = this.state; + + return + { isVisible && + event.stopPropagation() } + position="middle left" + headerTitle={ __('Media Library') } + > + + + } + { this.props.render({ open: this.openPopover }) } + ; + } +} + +export default withSelect(select => ({ + mediaLibrary: select('core/editor').getEditorSettings().mediaLibrary, +}))(MediaUpload); From 33d4c8fed86f060121a0c75b37734dda4a6e2a64 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 11:28:35 +0100 Subject: [PATCH 11/27] feat: Move media-upload to packages/edit-post --- .../hooks/components/media-upload/index.js | 105 ------------------ 1 file changed, 105 deletions(-) delete mode 100644 src/js/gutenberg-overrides/edit-post/hooks/components/media-upload/index.js diff --git a/src/js/gutenberg-overrides/edit-post/hooks/components/media-upload/index.js b/src/js/gutenberg-overrides/edit-post/hooks/components/media-upload/index.js deleted file mode 100644 index c7c570e..0000000 --- a/src/js/gutenberg-overrides/edit-post/hooks/components/media-upload/index.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * External dependencies - */ -import React, { Component, Fragment } from 'react'; -import { get } from 'lodash'; - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { Popover } from '@wordpress/components'; -import { withSelect } from '@wordpress/data'; - -class MediaContainer extends Component { - constructor (props) { - super(props); - - this.onImageClick = this.onImageClick.bind(this); - } - - onImageClick (img) { - const { onSelect, closePopover, gallery = false, multiple = false } = this.props; - - if (gallery || multiple) { - onSelect([{ ...img, url: img.source_url }]); - } - else { - onSelect({ ...img, url: img.source_url }); - } - - closePopover(); - } - - render () { - const { images } = this.props; - - return ( -
- { images && images.map(img => { - const source_url = get(img, 'media_details.sizes.thumbnail.source_url', img.source_url); - return ; - }) } -
- ); - } -} - -const MediaLibrary = withSelect(select => ({ - images: select('core').getMediaItems(), -}))(MediaContainer); - -class MediaUpload extends Component { - constructor (props) { - super(props); - this.state = { isVisible: false }; - - this.openPopover = this.openPopover.bind(this); - this.closePopover = this.closePopover.bind(this); - } - - openPopover () { - this.setState({ isVisible: true }); - } - - closePopover () { - this.setState({ isVisible: false }); - } - - render () { - if (!this.props.mediaLibrary) { - // console.log('Media Library is deactivated'); - return false; - } - - - const { isVisible } = this.state; - - return - { isVisible && - event.stopPropagation() } - position="middle left" - headerTitle={ __('Media Library') } - > - - - } - { this.props.render({ open: this.openPopover }) } - ; - } -} - -export default withSelect(select => ({ - mediaLibrary: select('core/editor').getEditorSettings().mediaLibrary, -}))(MediaUpload); From 6652a9f7c1dadb789f06241d6970961a228f7230 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 12:02:53 +0100 Subject: [PATCH 12/27] feat: Rename cover block and update it according gutenberg 4.0 --- .../packages/block-library/CHANGELOG.md | 6 + .../build-module/cover-image/index.js | 212 ------------ .../block-library/build-module/cover/index.js | 322 ++++++++++++++++++ 3 files changed, 328 insertions(+), 212 deletions(-) delete mode 100644 src/js/gutenberg-overrides/packages/block-library/build-module/cover-image/index.js create mode 100644 src/js/gutenberg-overrides/packages/block-library/build-module/cover/index.js diff --git a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md index eeb7179..aa7c1ec 100644 --- a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md @@ -1,5 +1,11 @@ # block-library changelog +## 2.7.0 2018-10-25 + +### Changed + +- 'cover-image' to 'cover' block ([packages/block-libary/build-module/cover](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/cover)) + ## 2.0.0 2018-08 ### Changed diff --git a/src/js/gutenberg-overrides/packages/block-library/build-module/cover-image/index.js b/src/js/gutenberg-overrides/packages/block-library/build-module/cover-image/index.js deleted file mode 100644 index e1d87a9..0000000 --- a/src/js/gutenberg-overrides/packages/block-library/build-module/cover-image/index.js +++ /dev/null @@ -1,212 +0,0 @@ -/** - * External dependencies - */ -import React from 'react'; -import { isEmpty } from 'lodash'; -import classnames from 'classnames'; - -/** - * WordPress dependencies - */ -import { IconButton, PanelBody, RangeControl, ToggleControl, Toolbar, withNotices } from '@wordpress/components'; -import { Fragment } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; -import { - BlockControls, - InspectorControls, - BlockAlignmentToolbar, - MediaPlaceholder, - MediaUpload, - AlignmentToolbar, - RichText, -} from '@wordpress/editor'; - -import * as others from 'gutenberg/packages/block-library/build-module/cover-image/index?source=node_modules'; - -function dimRatioToClass (ratio) { - return (ratio === 0 || ratio === 50) ? - null : - 'has-background-dim-' + (10 * Math.round(ratio / 10)); -} - -function backgroundImageStyles (url) { - return url ? - { backgroundImage: `url(${url})` } : - undefined; -} - -// added data attributes (which is an object) -others.settings.attributes.data = { - type: 'object', - default: {}, -}; - -// overrired edit function to add data attributes -others.settings.edit = withNotices(({ attributes, setAttributes, isSelected, className, noticeOperations, noticeUI }) => { - const { url, title, align, contentAlign, id, hasParallax, dimRatio, data } = attributes; - const updateAlignment = nextAlign => setAttributes({ align: nextAlign }); - const onSelectImage = media => { - if (! media || ! media.url) { - setAttributes({ url: undefined, id: undefined }); - return; - } - - const toUpdate = { url: media.url, id: media.id }; - - if (media.data) { - toUpdate.data = Object.keys(media.data) - .reduce((result, key) => { - result[`data-${key.replace('_', '-')}`] = media.data[key]; - - return result; - }, {}); - } - - setAttributes(toUpdate); - }; - const toggleParallax = () => setAttributes({ hasParallax: ! hasParallax }); - const setDimRatio = ratio => setAttributes({ dimRatio: ratio }); - - const style = backgroundImageStyles(url); - const classes = classnames( - className, - contentAlign !== 'center' && `has-${contentAlign}-content`, - dimRatioToClass(dimRatio), - { - 'has-background-dim': dimRatio !== 0, - 'has-parallax': hasParallax, - } - ); - - const controls = ( - - - - { - setAttributes({ contentAlign: nextAlign }); - } } - /> - - ( - - ) } - /> - - - { !! url && ( - - - - - - - ) } - - ); - - if (! url) { - const hasTitle = ! isEmpty(title); - const icon = hasTitle ? undefined : 'format-image'; - const label = hasTitle ? ( - setAttributes({ title: value }) } - inlineToolbar - /> - ) : __('Cover Image'); - - return ( - - { controls } - - - ); - } - - return ( - - { controls } -
- { (! RichText.isEmpty(title) || isSelected) && ( - setAttributes({ title: value }) } - inlineToolbar - /> - ) } -
-
- ); -}); - -// overrired save function to add data attributes -others.settings.save = ({ attributes, className }) => { - const { url, title, hasParallax, dimRatio, align, contentAlign, data } = attributes; - const style = backgroundImageStyles(url); - const classes = classnames( - className, - dimRatioToClass(dimRatio), - { - 'has-background-dim': dimRatio !== 0, - 'has-parallax': hasParallax, - [ `has-${contentAlign}-content` ]: contentAlign !== 'center', - }, - align ? `align${align}` : null, - ); - - return ( -
- { ! RichText.isEmpty(title) && ( - - ) } -
- ); -}; - -export * from 'gutenberg/packages/block-library/build-module/cover-image/index?source=node_modules'; diff --git a/src/js/gutenberg-overrides/packages/block-library/build-module/cover/index.js b/src/js/gutenberg-overrides/packages/block-library/build-module/cover/index.js new file mode 100644 index 0000000..5c1f01c --- /dev/null +++ b/src/js/gutenberg-overrides/packages/block-library/build-module/cover/index.js @@ -0,0 +1,322 @@ +/** + * External dependencies + */ +import React from 'react'; +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { IconButton, PanelBody, RangeControl, ToggleControl, Toolbar, withNotices } from '@wordpress/components'; +import { Fragment } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { compose } from '@wordpress/compose'; +import { + BlockControls, + InspectorControls, + BlockAlignmentToolbar, + MediaPlaceholder, + MediaUpload, + AlignmentToolbar, + PanelColorSettings, + RichText, + withColors, + getColorClassName, +} from '@wordpress/editor'; + +import * as others from 'gutenberg/packages/block-library/build-module/cover/index?source=node_modules'; + +function dimRatioToClass (ratio) { + return (ratio === 0 || ratio === 50) ? + null : + 'has-background-dim-' + (10 * Math.round(ratio / 10)); +} + +function backgroundImageStyles (url) { + return url ? + { backgroundImage: `url(${url})` } : + {}; +} + +const ALLOWED_MEDIA_TYPES = [ 'image', 'video' ]; +const IMAGE_BACKGROUND_TYPE = 'image'; +const VIDEO_BACKGROUND_TYPE = 'video'; + +// added data attributes (which is an object) +others.settings.attributes.data = { + type: 'object', + default: {}, +}; + +// overrired edit function to add data attributes +others.settings.edit = compose([ + withColors({ overlayColor: 'background-color' }), + withNotices, +])( + ({ attributes, setAttributes, isSelected, className, noticeOperations, noticeUI, overlayColor, setOverlayColor }) => { + const { + align, + backgroundType, + contentAlign, + dimRatio, + hasParallax, + id, + title, + url, + data, // GUTENBERG-JS + } = attributes; + const updateAlignment = nextAlign => setAttributes({ align: nextAlign }); + const onSelectMedia = media => { + if (! media || ! media.url) { + setAttributes({ url: undefined, id: undefined }); + return; + } + let mediaType; + // for media selections originated from a file upload. + if (media.media_type) { + if (media.media_type === IMAGE_BACKGROUND_TYPE) { + mediaType = IMAGE_BACKGROUND_TYPE; + } + else { + // only images and videos are accepted so if the media_type is not an image we can assume it is a video. + // Videos contain the media type of 'file' in the object returned from the rest api. + mediaType = VIDEO_BACKGROUND_TYPE; + } + } + else { // for media selections originated from existing files in the media library. + if ( + media.type !== IMAGE_BACKGROUND_TYPE && + media.type !== VIDEO_BACKGROUND_TYPE + ) { + return; + } + mediaType = media.type; + } + + // GUTENBERG-JS + const toUpdate = { + url: media.url, + id: media.id, + backgroundType: mediaType, + }; + + if (media.data) { + toUpdate.data = Object.keys(media.data) + .reduce((result, key) => { + result[`data-${key.replace('_', '-')}`] = media.data[key]; + + return result; + }, {}); + } + + setAttributes(toUpdate); + }; + const toggleParallax = () => setAttributes({ hasParallax: ! hasParallax }); + const setDimRatio = ratio => setAttributes({ dimRatio: ratio }); + const setTitle = newTitle => setAttributes({ title: newTitle }); + + const style = { + ...( + backgroundType === IMAGE_BACKGROUND_TYPE ? + backgroundImageStyles(url) : + {} + ), + backgroundColor: overlayColor.color, + }; + + const classes = classnames( + className, + contentAlign !== 'center' && `has-${contentAlign}-content`, + dimRatioToClass(dimRatio), + { + 'has-background-dim': dimRatio !== 0, + 'has-parallax': hasParallax, + } + ); + + const controls = ( + + + + { !! url && ( + + { + setAttributes({ contentAlign: nextAlign }); + } } + /> + + ( + + ) } + /> + + + ) } + + { !! url && ( + + + { IMAGE_BACKGROUND_TYPE === backgroundType && ( + + ) } + + + + + + ) } + + ); + + if (! url) { + const hasTitle = ! RichText.isEmpty(title); + const icon = hasTitle ? undefined : 'format-image'; + const label = hasTitle ? ( + + ) : __('Cover'); + + return ( + + { controls } + + + ); + } + + return ( + + { controls } +
+ { VIDEO_BACKGROUND_TYPE === backgroundType && ( +
+
+ ); + } +); + +// overrired save function to add data attributes +others.settings.save = ({ attributes, className }) => { + const { + align, + backgroundType, + contentAlign, + customOverlayColor, + dimRatio, + hasParallax, + overlayColor, + title, + url, + data, + } = attributes; + const overlayColorClass = getColorClassName('background-color', overlayColor); + const style = backgroundType === IMAGE_BACKGROUND_TYPE ? + backgroundImageStyles(url) : + {}; + if (! overlayColorClass) { + style.backgroundColor = customOverlayColor; + } + + const classes = classnames( + className, + dimRatioToClass(dimRatio), + overlayColorClass, + { + 'has-background-dim': dimRatio !== 0, + 'has-parallax': hasParallax, + [ `has-${contentAlign}-content` ]: contentAlign !== 'center', + }, + align ? `align${align}` : null, + ); + + return ( +
+ { VIDEO_BACKGROUND_TYPE === backgroundType && url && (
+ + ); +}; + +export * from 'gutenberg/packages/block-library/build-module/cover/index?source=node_modules'; From 54675e463f4375fa5ea5896549d5f1422f133f95 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 12:22:45 +0100 Subject: [PATCH 13/27] feat: Update gallery block --- .../packages/block-library/CHANGELOG.md | 2 ++ .../block-library/build-module/gallery/edit.js | 18 ++++++++++-------- .../build-module/gallery/gallery-image.js | 7 ++++--- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md index aa7c1ec..6b99b16 100644 --- a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md @@ -6,6 +6,8 @@ - 'cover-image' to 'cover' block ([packages/block-libary/build-module/cover](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/cover)) +- 'gallery' block ([packages/block-libary/build-module/gallery/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/gallery/gallery-image.js)) and ([packages/block-libary/build-module/gallery/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/gallery/gallery-image.js)) + ## 2.0.0 2018-08 ### Changed diff --git a/src/js/gutenberg-overrides/packages/block-library/build-module/gallery/edit.js b/src/js/gutenberg-overrides/packages/block-library/build-module/gallery/edit.js index ab0c247..e2b3cfd 100644 --- a/src/js/gutenberg-overrides/packages/block-library/build-module/gallery/edit.js +++ b/src/js/gutenberg-overrides/packages/block-library/build-module/gallery/edit.js @@ -2,7 +2,7 @@ * External Dependencies */ import React from 'react'; -import { filter, pick } from 'lodash'; +import { filter } from 'lodash'; /** * WordPress dependencies @@ -41,8 +41,9 @@ const linkOptions = [ { value: 'media', label: __('Media File') }, { value: 'none', label: __('None') }, ]; +const ALLOWED_MEDIA_TYPES = [ 'image' ]; -const { defaultColumnsNumber } = others; +const { defaultColumnsNumber, pickRelevantMediaFiles } = others; class GalleryEdit extends Component { constructor (props) { @@ -87,7 +88,7 @@ class GalleryEdit extends Component { onSelectImages (images) { this.props.setAttributes({ - images: images.map(image => pick(image, [ 'alt', 'caption', 'id', 'link', 'url' ])), + images: images.map(image => pickRelevantMediaFiles(image)), }); } @@ -132,11 +133,12 @@ class GalleryEdit extends Component { const currentImages = this.props.attributes.images || []; const { noticeOperations, setAttributes } = this.props; mediaUpload({ - allowedType: 'image', + allowedTypes: ALLOWED_MEDIA_TYPES, filesList: files, onFileChange: images => { + const imagesNormalized = images.map(image => pickRelevantMediaFiles(image)); setAttributes({ - images: currentImages.concat(images), + images: currentImages.concat(imagesNormalized), }); }, onError: noticeOperations.createErrorNotice, @@ -169,7 +171,7 @@ class GalleryEdit extends Component { img.id) } @@ -200,7 +202,7 @@ class GalleryEdit extends Component { } } onSelect={ this.onSelectImages } accept="image/*" - type="image" + allowedTypes={ ALLOWED_MEDIA_TYPES } multiple notices={ noticeUI } onError={ noticeOperations.createErrorNotice } @@ -228,7 +230,7 @@ class GalleryEdit extends Component { help={ this.getImageCropHelp } /> } { href ? { img } : img } - { (caption && caption.length > 0) || isSelected ? ( + { (! RichText.isEmpty(caption) || isSelected) ? ( Date: Thu, 25 Oct 2018 12:41:29 +0100 Subject: [PATCH 14/27] feat: Update image block --- scripts/install.sh | 2 +- .../packages/block-library/CHANGELOG.md | 4 +- .../block-library/build-module/image/edit.js | 160 +++++++++++++----- 3 files changed, 124 insertions(+), 42 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 75c0348..4845296 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -13,7 +13,7 @@ git clone https://github.com/WordPress/gutenberg.git cd gutenberg # checkout to version we want -git checkout tags/v4.0.0 +git checkout tags/v4.1.0 # remove git references # GUTENBERG HAS A SUBMODULE NOW diff --git a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md index 6b99b16..0d1d7ed 100644 --- a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md @@ -6,7 +6,9 @@ - 'cover-image' to 'cover' block ([packages/block-libary/build-module/cover](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/cover)) -- 'gallery' block ([packages/block-libary/build-module/gallery/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/gallery/gallery-image.js)) and ([packages/block-libary/build-module/gallery/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/gallery/gallery-image.js)) +- 'gallery' block ([packages/block-libary/build-module/gallery/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/gallery/edit.js)) and ([packages/block-libary/build-module/gallery/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/gallery/gallery-image.js)) + +- 'image' block ([packages/block-libary/build-module/image/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/image/edit.js)) ## 2.0.0 2018-08 diff --git a/src/js/gutenberg-overrides/packages/block-library/build-module/image/edit.js b/src/js/gutenberg-overrides/packages/block-library/build-module/image/edit.js index bff62fd..b3e7a7f 100644 --- a/src/js/gutenberg-overrides/packages/block-library/build-module/image/edit.js +++ b/src/js/gutenberg-overrides/packages/block-library/build-module/image/edit.js @@ -3,7 +3,6 @@ */ import React from 'react'; import classnames from 'classnames'; -import ResizableBox from 're-resizable'; import { get, isEmpty, @@ -17,12 +16,13 @@ import { */ import { __ } from '@wordpress/i18n'; import { Component, Fragment } from '@wordpress/element'; -import { getBlobByURL, revokeBlobURL } from '@wordpress/blob'; +import { getBlobByURL, revokeBlobURL, isBlobURL } from '@wordpress/blob'; import { Button, ButtonGroup, IconButton, PanelBody, + ResizableBox, SelectControl, TextControl, TextareaControl, @@ -55,24 +55,56 @@ const LINK_DESTINATION_NONE = 'none'; const LINK_DESTINATION_MEDIA = 'media'; const LINK_DESTINATION_ATTACHMENT = 'attachment'; const LINK_DESTINATION_CUSTOM = 'custom'; +const ALLOWED_MEDIA_TYPES = [ 'image' ]; + +export const pickRelevantMediaFiles = image => { + return pick(image, [ 'alt', 'id', 'link', 'url', 'caption' ]); +}; + +/** + * Is the URL a temporary blob URL? A blob URL is one that is used temporarily + * while the image is being uploaded and will not have an id yet allocated. + * + * @param {number=} id The id of the image. + * @param {string=} url The url of the image. + * + * @return {boolean} Is the URL a Blob URL + */ +const isTemporaryImage = (id, url) => ! id && isBlobURL(url); + +/** + * Is the url for the image hosted externally. An externally hosted image has no id + * and is not a blob url. + * + * @param {number=} id The id of the image. + * @param {string=} url The url of the image. + * + * @return {boolean} Is the url an externally hosted url? + */ +const isExternalImage = (id, url) => url && ! id && ! isBlobURL(url); class ImageEdit extends Component { constructor (props) { super(props); + const { attributes } = props; + this.updateAlt = this.updateAlt.bind(this); this.updateAlignment = this.updateAlignment.bind(this); this.onFocusCaption = this.onFocusCaption.bind(this); this.onImageClick = this.onImageClick.bind(this); this.onSelectImage = this.onSelectImage.bind(this); + this.onSelectURL = this.onSelectURL.bind(this); this.updateImageURL = this.updateImageURL.bind(this); this.updateWidth = this.updateWidth.bind(this); this.updateHeight = this.updateHeight.bind(this); this.updateDimensions = this.updateDimensions.bind(this); this.onSetCustomHref = this.onSetCustomHref.bind(this); this.onSetLinkDestination = this.onSetLinkDestination.bind(this); + this.toggleIsEditing = this.toggleIsEditing.bind(this); this.state = { captionFocused: false, + isEditing: ! attributes.url, }; } @@ -80,26 +112,26 @@ class ImageEdit extends Component { const { attributes, setAttributes } = this.props; const { id, url = '' } = attributes; - if (! id && url.indexOf('blob:') === 0) { + if (isTemporaryImage(id, url)) { const file = getBlobByURL(url); if (file) { mediaUpload({ filesList: [ file ], onFileChange: ([ image ]) => { - setAttributes({ ...image }); + setAttributes(pickRelevantMediaFiles(image)); }, - allowedType: 'image', + allowedTypes: ALLOWED_MEDIA_TYPES, }); } } } componentDidUpdate (prevProps) { - const { id: prevID, url: prevUrl = '' } = prevProps.attributes; + const { id: prevID, url: prevURL = '' } = prevProps.attributes; const { id, url = '' } = this.props.attributes; - if (! prevID && prevUrl.indexOf('blob:') === 0 && id && url.indexOf('blob:') === -1) { + if (isTemporaryImage(prevID, prevURL) && ! isTemporaryImage(id, url)) { revokeBlobURL(url); } @@ -120,8 +152,13 @@ class ImageEdit extends Component { }); return; } + + this.setState({ + isEditing: false, + }); + const toUpdate = { - ...pick(media, [ 'alt', 'id', 'caption', 'url' ]), + ...pickRelevantMediaFiles(media), width: undefined, height: undefined, }; @@ -160,6 +197,21 @@ class ImageEdit extends Component { }); } + onSelectURL (newURL) { + const { url } = this.props.attributes; + + if (newURL !== url) { + this.props.setAttributes({ + url: newURL, + id: undefined, + }); + } + + this.setState({ + isEditing: false, + }); + } + onSetCustomHref (value) { this.props.setAttributes({ href: value }); } @@ -222,9 +274,52 @@ class ImageEdit extends Component { ]; } + toggleIsEditing () { + this.setState({ + isEditing: ! this.state.isEditing, + }); + } + render () { + const { isEditing } = this.state; const { attributes, setAttributes, isLargeViewport, isSelected, className, maxWidth, noticeOperations, noticeUI, toggleSelection, isRTL } = this.props; const { url, alt, caption, align, id, href, linkDestination, width, height, data } = attributes; + const isExternal = isExternalImage(id, url); + + let toolbarEditButton; + if (url) { + if (isExternal) { + toolbarEditButton = ( + + + + ); + } + else { + toolbarEditButton = ( + + ( + + ) } + /> + + ); + } + } const controls = ( @@ -232,26 +327,12 @@ class ImageEdit extends Component { value={ align } onChange={ this.updateAlignment } /> - - - ( - - ) } - /> - + { toolbarEditButton } ); - if (! url) { + if (isEditing) { + const src = isExternal ? url : undefined; return ( { controls } @@ -263,17 +344,19 @@ class ImageEdit extends Component { } } className={ className } onSelect={ this.onSelectImage } + onSelectURL={ this.onSelectURL } notices={ noticeUI } onError={ noticeOperations.createErrorNotice } accept="image/*" - type="image" + allowedTypes={ ALLOWED_MEDIA_TYPES } + value={ { id, src } } /> ); } const classes = classnames(className, { - 'is-transient': 0 === url.indexOf('blob:'), + 'is-transient': isBlobURL(url), 'is-resized': !! width || !! height, 'is-focused': isSelected, }); @@ -365,13 +448,15 @@ class ImageEdit extends Component { options={ this.getLinkDestinationOptions() } onChange={ this.onSetLinkDestination } /> - + { linkDestination !== LINK_DESTINATION_NONE && ( + + ) } ); @@ -462,11 +547,6 @@ class ImageEdit extends Component { minHeight={ minHeight } maxHeight={ maxWidth / ratio } lockAspectRatio - handleClasses={ { - right: 'wp-block-image__resize-handler-right', - bottom: 'wp-block-image__resize-handler-bottom', - left: 'wp-block-image__resize-handler-left', - } } enable={ { top: false, right: showRightHandle, @@ -494,7 +574,7 @@ class ImageEdit extends Component { setAttributes({ caption: value }) } isSelected={ this.state.captionFocused } From 2fbef60e07e7fddccbe4800d6b30daf3e2b7a98d Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 12:43:59 +0100 Subject: [PATCH 15/27] feat: Update getBlockAttribute in api/parser --- .../packages/blocks/CHANGELOG.md | 6 +++ .../blocks/build-module/api/parser.js | 39 +++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/js/gutenberg-overrides/packages/blocks/CHANGELOG.md b/src/js/gutenberg-overrides/packages/blocks/CHANGELOG.md index 8d2ec30..d7e8494 100644 --- a/src/js/gutenberg-overrides/packages/blocks/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/blocks/CHANGELOG.md @@ -1,5 +1,11 @@ # blocks changelog +## 2.7.0 2018-10-25 + +### Changed + +- 'getBlockAttribute' according last updates ([packages/blocks/build-module/api/parser.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/blocks/build-module/api/parser.js)) + ## 2.0.0 2018-08 ### Changed diff --git a/src/js/gutenberg-overrides/packages/blocks/build-module/api/parser.js b/src/js/gutenberg-overrides/packages/blocks/build-module/api/parser.js index d122b3b..c2d6d09 100644 --- a/src/js/gutenberg-overrides/packages/blocks/build-module/api/parser.js +++ b/src/js/gutenberg-overrides/packages/blocks/build-module/api/parser.js @@ -1,12 +1,17 @@ /** * External dependencies */ -import { get, kebabCase, map, mapKeys } from 'lodash'; +import { get, kebabCase, map, mapKeys, castArray } from 'lodash'; import jQuery from 'jquery'; +/** + * WordPress dependencies + */ +import deprecated from '@wordpress/deprecated'; + import def, * as others from 'gutenberg/packages/blocks/build-module/api/parser?source=node_modules'; -const { asType, parseWithAttributeSchema } = others; +const { asType, parseWithAttributeSchema, isAmbiguousStringSource, isOfTypes } = others; /** * [parseDataAttributes description] @@ -48,7 +53,9 @@ function parseDataAttributes (innerHTML, attributeSchema, value) { } others.getBlockAttribute = (attributeKey, attributeSchema, innerHTML, commentAttributes) => { + const { type } = attributeSchema; let value, data; + switch (attributeSchema.source) { // undefined source means that it's an attribute serialized to the block's "comment" case undefined: @@ -74,7 +81,33 @@ others.getBlockAttribute = (attributeKey, attributeSchema, innerHTML, commentAtt break; } - return value === undefined ? attributeSchema.default : asType(value, attributeSchema.type); + if (value !== undefined) { + if (isAmbiguousStringSource(attributeSchema)) { + if (! isOfTypes(value, castArray(type))) { + deprecated('Attribute type coercion', { + plugin: 'Gutenberg', + version: '4.2', + hint: ( + 'Omit the source to preserve type via serialized ' + + 'comment demarcation.' + ), + }); + + value = asType(value, type); + } + } + else if (type !== undefined && ! isOfTypes(value, castArray(type))) { + // Reject the value if it is not valid of type. Reverting to the + // undefined value ensures the default is restored, if applicable. + value = undefined; + } + } + + if (value === undefined) { + return attributeSchema.default; + } + + return value; }; export default def; From df086cb7be5e703c359e997580089be4117282f4 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 16:15:42 +0100 Subject: [PATCH 16/27] feat: Remove BlockListBlock override --- .../packages/editor/CHANGELOG.md | 4 + .../components/block-list/block.js | 693 ------------------ 2 files changed, 4 insertions(+), 693 deletions(-) delete mode 100644 src/js/gutenberg-overrides/packages/editor/build-module/components/block-list/block.js diff --git a/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md b/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md index 751bdad..f3dcf87 100644 --- a/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md @@ -2,6 +2,10 @@ ## 2.7.0 2018-10-25 +### Removed + +- BlockListBlock override + ### Added - `addQueryArgs` to 'Manage All Reusable Blocks' link (Inserter Menu) ([packages/editor/build-module/components/inserter/menu.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/editor/build-module/components/inserter/menu.js)) diff --git a/src/js/gutenberg-overrides/packages/editor/build-module/components/block-list/block.js b/src/js/gutenberg-overrides/packages/editor/build-module/components/block-list/block.js deleted file mode 100644 index a9fb776..0000000 --- a/src/js/gutenberg-overrides/packages/editor/build-module/components/block-list/block.js +++ /dev/null @@ -1,693 +0,0 @@ -/** - * External dependencies - */ -import React from 'react'; -import classnames from 'classnames'; -import { get, reduce, size, castArray, first, last } from 'lodash'; - -/** - * WordPress dependencies - */ -import { Component, findDOMNode, Fragment } from '@wordpress/element'; -import { - focus, - isTextField, - placeCaretAtHorizontalEdge, - placeCaretAtVerticalEdge, -} from '@wordpress/dom'; -import { BACKSPACE, DELETE, ENTER } from '@wordpress/keycodes'; -import { - cloneBlock, - getBlockType, - getSaveElement, - isReusableBlock, - isUnmodifiedDefaultBlock, -} from '@wordpress/blocks'; -import { withFilters } from '@wordpress/components'; -import { __, sprintf } from '@wordpress/i18n'; -import { withDispatch, withSelect } from '@wordpress/data'; -import { withViewportMatch } from '@wordpress/viewport'; -import { compose } from '@wordpress/compose'; - -/** - * Internal dependencies - */ -import BlockEdit from '../block-edit'; -import BlockMover from '../block-mover'; -import BlockDropZone from '../block-drop-zone'; -import BlockInvalidWarning from './block-invalid-warning'; -import BlockCrashWarning from './block-crash-warning'; -import BlockCrashBoundary from './block-crash-boundary'; -import BlockHtml from './block-html'; -import BlockBreadcrumb from './breadcrumb'; -import BlockContextualToolbar from './block-contextual-toolbar'; -import BlockMultiControls from './multi-controls'; -import BlockMobileToolbar from './block-mobile-toolbar'; -import BlockInsertionPoint from './insertion-point'; -import IgnoreNestedEvents from './ignore-nested-events'; -import InserterWithShortcuts from '../inserter-with-shortcuts'; -import Inserter from '../inserter'; -import withHoverAreas from './with-hover-areas'; - -export class BlockListBlock extends Component { - constructor (props) { - super(props); - - this.setBlockListRef = this.setBlockListRef.bind(this); - this.bindBlockNode = this.bindBlockNode.bind(this); - this.setAttributes = this.setAttributes.bind(this); - this.maybeHover = this.maybeHover.bind(this); - this.hideHoverEffects = this.hideHoverEffects.bind(this); - this.mergeBlocks = this.mergeBlocks.bind(this); - this.insertBlocksAfter = this.insertBlocksAfter.bind(this); - this.onFocus = this.onFocus.bind(this); - this.preventDrag = this.preventDrag.bind(this); - this.onPointerDown = this.onPointerDown.bind(this); - this.deleteOrInsertAfterWrapper = this.deleteOrInsertAfterWrapper.bind(this); - this.onBlockError = this.onBlockError.bind(this); - this.onTouchStart = this.onTouchStart.bind(this); - this.onClick = this.onClick.bind(this); - this.onDragStart = this.onDragStart.bind(this); - this.onDragEnd = this.onDragEnd.bind(this); - this.selectOnOpen = this.selectOnOpen.bind(this); - this.hadTouchStart = false; - - this.state = { - error: null, - dragging: false, - isHovered: false, - }; - } - - componentDidMount () { - if (this.props.isSelected) { - this.focusTabbable(); - } - } - - componentDidUpdate (prevProps) { - if (this.props.isTypingWithinBlock || this.props.isSelected) { - this.hideHoverEffects(); - } - - if (this.props.isSelected && ! prevProps.isSelected) { - this.focusTabbable(); - } - } - - setBlockListRef (node) { - // Disable reason: The root return element uses a component to manage - // event nesting, but the parent block list layout needs the raw DOM - // node to track multi-selection. - // - // eslint-disable-next-line react/no-find-dom-node - node = findDOMNode(node); - - this.wrapperNode = node; - - this.props.blockRef(node, this.props.clientId); - } - - bindBlockNode (node) { - // Disable reason: The block element uses a component to manage event - // nesting, but we rely on a raw DOM node for focusing. - // - // eslint-disable-next-line react/no-find-dom-node - this.node = findDOMNode(node); - } - - /** - * When a block becomes selected, transition focus to an inner tabbable. - */ - focusTabbable () { - const { initialPosition } = this.props; - - // Focus is captured by the wrapper node, so while focus transition - // should only consider tabbables within editable display, since it - // may be the wrapper itself or a side control which triggered the - // focus event, don't unnecessary transition to an inner tabbable. - if (this.wrapperNode.contains(document.activeElement)) { - return; - } - - // Find all tabbables within node. - const textInputs = focus.tabbable.find(this.node).filter(isTextField); - - // If reversed (e.g. merge via backspace), use the last in the set of - // tabbables. - const isReverse = -1 === initialPosition; - const target = (isReverse ? last : first)(textInputs); - - if (! target) { - this.wrapperNode.focus(); - return; - } - - target.focus(); - - // In reverse case, need to explicitly place caret position. - if (isReverse) { - placeCaretAtHorizontalEdge(target, true); - placeCaretAtVerticalEdge(target, true); - } - } - - setAttributes (attributes) { - const { block, onChange } = this.props; - const type = getBlockType(block.name); - onChange(block.clientId, attributes); - - const metaAttributes = reduce(attributes, (result, value, key) => { - if (get(type, [ 'attributes', key, 'source' ]) === 'meta') { - result[ type.attributes[ key ].meta ] = value; - } - - return result; - }, {}); - - if (size(metaAttributes)) { - this.props.onMetaChange({ - ...this.props.meta, - ...metaAttributes, - }); - } - } - - onTouchStart () { - // Detect touchstart to disable hover on iOS - this.hadTouchStart = true; - } - - onClick () { - // Clear touchstart detection - // Browser will try to emulate mouse events also see https://www.html5rocks.com/en/mobile/touchandmouse/ - this.hadTouchStart = false; - } - - /** - * A mouseover event handler to apply hover effect when a pointer device is - * placed within the bounds of the block. The mouseover event is preferred - * over mouseenter because it may be the case that a previous mouseenter - * event was blocked from being handled by a IgnoreNestedEvents component, - * therefore transitioning out of a nested block to the bounds of the block - * would otherwise not trigger a hover effect. - * - * @see https://developer.mozilla.org/en-US/docs/Web/Events/mouseenter - */ - maybeHover () { - const { isPartOfMultiSelection, isSelected } = this.props; - const { isHovered } = this.state; - - if (isHovered || isPartOfMultiSelection || isSelected || - this.props.isMultiSelecting || this.hadTouchStart) { - return; - } - - this.setState({ isHovered: true }); - } - - /** - * Sets the block state as unhovered if currently hovering. There are cases - * where mouseleave may occur but the block is not hovered (multi-select), - * so to avoid unnecesary renders, the state is only set if hovered. - */ - hideHoverEffects () { - if (this.state.isHovered) { - this.setState({ isHovered: false }); - } - } - - mergeBlocks (forward = false) { - const { block, previousBlockClientId, nextBlockClientId, onMerge } = this.props; - - // Do nothing when it's the first block. - if ( - (! forward && ! previousBlockClientId) || - (forward && ! nextBlockClientId) - ) { - return; - } - - if (forward) { - onMerge(block.clientId, nextBlockClientId); - } - else { - onMerge(previousBlockClientId, block.clientId); - } - } - - insertBlocksAfter (blocks) { - this.props.onInsertBlocks(blocks, this.props.order + 1); - } - - /** - * Marks the block as selected when focused and not already selected. This - * specifically handles the case where block does not set focus on its own - * (via `setFocus`), typically if there is no focusable input in the block. - * - * @return {void} - */ - onFocus () { - if (! this.props.isSelected && ! this.props.isPartOfMultiSelection) { - this.props.onSelect(); - } - } - - /** - * Prevents default dragging behavior within a block to allow for multi- - * selection to take effect unhampered. - * - * @param {DragEvent} event Drag event. - * - * @return {void} - */ - preventDrag (event) { - event.preventDefault(); - } - - /** - * Begins tracking cursor multi-selection when clicking down within block. - * - * @param {MouseEvent} event A mousedown event. - * - * @return {void} - */ - onPointerDown (event) { - // Not the main button. - // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button - if (event.button !== 0) { - return; - } - - if (event.shiftKey) { - if (! this.props.isSelected) { - this.props.onShiftSelection(this.props.clientId); - event.preventDefault(); - } - } - else { - this.props.onSelectionStart(this.props.clientId); - - // Allow user to escape out of a multi-selection to a singular - // selection of a block via click. This is handled here since - // onFocus excludes blocks involved in a multiselection, as - // focus can be incurred by starting a multiselection (focus - // moved to first block's multi-controls). - if (this.props.isPartOfMultiSelection) { - this.props.onSelect(); - } - } - } - - /** - * Interprets keydown event intent to remove or insert after block if key - * event occurs on wrapper node. This can occur when the block has no text - * fields of its own, particularly after initial insertion, to allow for - * easy deletion and continuous writing flow to add additional content. - * - * @param {KeyboardEvent} event Keydown event. - */ - deleteOrInsertAfterWrapper (event) { - const { keyCode, target } = event; - - if (target !== this.wrapperNode || this.props.isLocked) { - return; - } - - const { clientId, onRemove } = this.props; - - switch (keyCode) { - case ENTER: - // Insert default block after current block if enter and event - // not already handled by descendant. - this.props.onInsertDefaultBlockAfter(); - event.preventDefault(); - break; - - case BACKSPACE: - case DELETE: - // Remove block on backspace. - onRemove(clientId); - event.preventDefault(); - break; - } - } - - onBlockError (error) { - this.setState({ error }); - } - - onDragStart () { - this.setState({ dragging: true }); - } - - onDragEnd () { - this.setState({ dragging: false }); - } - - selectOnOpen (open) { - if (open && ! this.props.isSelected) { - this.props.onSelect(); - } - } - - render () { - const { - block, - order, - mode, - isFocusMode, - hasFixedToolbar, - isLocked, - isFirst, - isLast, - clientId, - rootClientId, - layout, - isSelected, - isPartOfMultiSelection, - isFirstMultiSelected, - isTypingWithinBlock, - isMultiSelecting, - hoverArea, - isEmptyDefaultBlock, - isMovable, - isPreviousBlockADefaultEmptyBlock, - hasSelectedInnerBlock, - isParentOfSelectedBlock, - hasMultiSelection, - isDraggable, - } = this.props; - const isHovered = this.state.isHovered && ! isMultiSelecting; - const { name: blockName, isValid } = block; - const blockType = getBlockType(blockName); - // translators: %s: Type of block (i.e. Text, Image etc) - const blockLabel = sprintf(__('Block: %s'), blockType.title); - // The block as rendered in the editor is composed of general block UI - // (mover, toolbar, wrapper) and the display of the block content. - - // If the block is selected and we're typing the block should not appear. - // Empty paragraph blocks should always show up as unselected. - const showEmptyBlockSideInserter = (isSelected || isHovered) && isEmptyDefaultBlock && isValid; - const showSideInserter = (isSelected || isHovered) && isEmptyDefaultBlock; - const shouldAppearSelected = ! isFocusMode && ! hasFixedToolbar && ! showSideInserter && isSelected && ! isTypingWithinBlock; - const shouldAppearSelectedParent = ! isFocusMode && ! hasFixedToolbar && ! showSideInserter && hasSelectedInnerBlock && ! isTypingWithinBlock && ! hasMultiSelection; - const shouldAppearHovered = ! isFocusMode && ! hasFixedToolbar && isHovered && ! isEmptyDefaultBlock; - // We render block movers and block settings to keep them tabbale even if hidden - const shouldRenderMovers = ! isFocusMode && (isSelected || hoverArea === 'left') && ! showEmptyBlockSideInserter && ! isMultiSelecting && ! isPartOfMultiSelection && ! isTypingWithinBlock; - const shouldShowBreadcrumb = ! isFocusMode && isHovered && ! isEmptyDefaultBlock; - const shouldShowContextualToolbar = ! hasFixedToolbar && ! showSideInserter && ((isSelected && ! isTypingWithinBlock) || isFirstMultiSelected); - const shouldShowMobileToolbar = shouldAppearSelected; - const { error, dragging } = this.state; - - // Insertion point can only be made visible when the side inserter is - // not present, and either the block is at the extent of a selection or - // is the first block in the top-level list rendering. - const shouldShowInsertionPoint = (isPartOfMultiSelection && isFirst) || ! isPartOfMultiSelection; - const canShowInBetweenInserter = ! isEmptyDefaultBlock && ! isPreviousBlockADefaultEmptyBlock; - - // Generate the wrapper class names handling the different states of the block. - const wrapperClassName = classnames('editor-block-list__block', { - 'has-warning': ! isValid || !! error, - 'is-selected': shouldAppearSelected, - 'is-multi-selected': isPartOfMultiSelection, - 'is-selected-parent': shouldAppearSelectedParent, - 'is-hovered': shouldAppearHovered, - 'is-reusable': isReusableBlock(blockType), - 'is-dragging': dragging, - 'is-typing': isTypingWithinBlock, - 'is-focused': isFocusMode && (isSelected || isParentOfSelectedBlock), - 'is-focus-mode': isFocusMode, - }); - - const { onReplace } = this.props; - - // Determine whether the block has props to apply to the wrapper. - let wrapperProps = this.props.wrapperProps; - if (blockType.getEditWrapperProps) { - wrapperProps = { - ...wrapperProps, - ...blockType.getEditWrapperProps(block.attributes), - }; - } - const blockElementId = `block-${clientId}`; - - // We wrap the BlockEdit component in a div that hides it when editing in - // HTML mode. This allows us to render all of the ancillary pieces - // (InspectorControls, etc.) which are inside `BlockEdit` but not - // `BlockHTML`, even in HTML mode. - let blockEdit = ( - - ); - if (mode !== 'visual') { - blockEdit =
{ blockEdit }
; - } - - // Disable reasons: - // - // jsx-a11y/mouse-events-have-key-events: - // - onMouseOver is explicitly handling hover effects - // - // jsx-a11y/no-static-element-interactions: - // - Each block can be selected by clicking on it - - /* eslint-disable jsx-a11y/mouse-events-have-key-events, jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */ - return ( - - { shouldShowInsertionPoint && ( - - ) } - - { shouldRenderMovers && ( - - ) } - { shouldShowBreadcrumb && ( - - ) } - { shouldShowContextualToolbar && } - { isFirstMultiSelected && ( - - ) } - - - { isValid && blockEdit } - { isValid && mode === 'html' && ( - - ) } - { ! isValid && [ - , -
- { getSaveElement(blockType, block.attributes) } -
, - ] } -
- { shouldShowMobileToolbar && ( - - ) } - { !! error && } -
- { showEmptyBlockSideInserter && ( - -
- -
-
- -
-
- ) } -
- ); - /* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */ - } -} - -const applyWithSelect = withSelect((select, { clientId, rootClientId, isLargeViewport }) => { - const { - isBlockSelected, - getPreviousBlockClientId, - getNextBlockClientId, - getBlock, - isAncestorMultiSelected, - isBlockMultiSelected, - isFirstMultiSelectedBlock, - isMultiSelecting, - isTyping, - getBlockIndex, - getEditedPostAttribute, - getBlockMode, - isSelectionEnabled, - getSelectedBlocksInitialCaretPosition, - getEditorSettings, - hasSelectedInnerBlock, - getTemplateLock, - hasMultiSelection, - } = select('core/editor'); - const isSelected = isBlockSelected(clientId); - const { hasFixedToolbar, focusMode } = getEditorSettings(); - const block = getBlock(clientId); - const previousBlockClientId = getPreviousBlockClientId(clientId); - const previousBlock = getBlock(previousBlockClientId); - const templateLock = getTemplateLock(rootClientId); - const isParentOfSelectedBlock = hasSelectedInnerBlock(clientId, true); - - return { - nextBlockClientId: getNextBlockClientId(clientId), - isPartOfMultiSelection: isBlockMultiSelected(clientId) || isAncestorMultiSelected(clientId), - isFirstMultiSelected: isFirstMultiSelectedBlock(clientId), - isMultiSelecting: isMultiSelecting(), - hasSelectedInnerBlock: hasSelectedInnerBlock(clientId, false), - // We only care about this prop when the block is selected - // Thus to avoid unnecessary rerenders we avoid updating the prop if the block is not selected. - isTypingWithinBlock: (isSelected || isParentOfSelectedBlock) && isTyping(), - order: getBlockIndex(clientId, rootClientId), - meta: getEditedPostAttribute('meta'), - mode: getBlockMode(clientId), - isSelectionEnabled: isSelectionEnabled(), - initialPosition: getSelectedBlocksInitialCaretPosition(), - isEmptyDefaultBlock: block && isUnmodifiedDefaultBlock(block), - isPreviousBlockADefaultEmptyBlock: previousBlock && isUnmodifiedDefaultBlock(previousBlock), - isMovable: 'all' !== templateLock, - isLocked: !! templateLock, - isFocusMode: focusMode && isLargeViewport, - hasFixedToolbar: hasFixedToolbar && isLargeViewport, - previousBlockClientId, - block, - isSelected, - isParentOfSelectedBlock, - hasMultiSelection: hasMultiSelection(), - }; -}); - -const applyWithDispatch = withDispatch((dispatch, ownProps) => { - const { - updateBlockAttributes, - selectBlock, - insertBlocks, - insertDefaultBlock, - removeBlock, - mergeBlocks, - replaceBlocks, - editPost, - toggleSelection, - } = dispatch('core/editor'); - - return { - onChange (clientId, attributes) { - updateBlockAttributes(clientId, attributes); - }, - onSelect (clientId = ownProps.clientId, initialPosition) { - selectBlock(clientId, initialPosition); - }, - onInsertBlocks (blocks, index) { - const { rootClientId, layout } = ownProps; - blocks = blocks.map(block => cloneBlock(block, { layout })); - insertBlocks(blocks, index, rootClientId); - }, - onInsertDefaultBlockAfter () { - const { order, rootClientId } = ownProps; - insertDefaultBlock({}, rootClientId, order + 1); - }, - onRemove (clientId) { - removeBlock(clientId); - }, - onMerge (...args) { - mergeBlocks(...args); - }, - onReplace (blocks) { - const { layout } = ownProps; - blocks = castArray(blocks).map(block => ( - cloneBlock(block, { layout }) - )); - replaceBlocks([ ownProps.clientId ], blocks); - }, - onMetaChange (meta) { - editPost({ meta }); - }, - toggleSelection (selectionEnabled) { - toggleSelection(selectionEnabled); - }, - }; -}); - -export default compose( - withViewportMatch({ isLargeViewport: 'medium' }), - applyWithSelect, - applyWithDispatch, - withFilters('editor.BlockListBlock'), - withHoverAreas, -)(BlockListBlock); From d7d49edd579e2664b294626a9333748e76d9e6c4 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 16:16:07 +0100 Subject: [PATCH 17/27] feat: Update BlockDropZone component --- .../components/block-drop-zone/index.js | 79 ++++++++++++------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/src/js/gutenberg-overrides/packages/editor/build-module/components/block-drop-zone/index.js b/src/js/gutenberg-overrides/packages/editor/build-module/components/block-drop-zone/index.js index b843442..7519b3d 100644 --- a/src/js/gutenberg-overrides/packages/editor/build-module/components/block-drop-zone/index.js +++ b/src/js/gutenberg-overrides/packages/editor/build-module/components/block-drop-zone/index.js @@ -1,5 +1,5 @@ /** - * External dependencies + * External Dependencies */ import React from 'react'; import { castArray } from 'lodash'; @@ -19,6 +19,28 @@ import { Component } from '@wordpress/element'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; +const parseDropEvent = event => { + let result = { + srcRootClientId: null, + srcClientId: null, + srcIndex: null, + type: null, + }; + + if (! event.dataTransfer) { + return result; + } + + try { + result = Object.assign(result, JSON.parse(event.dataTransfer.getData('text'))); + } + catch (err) { + return result; + } + + return result; +}; + class BlockDropZone extends Component { constructor (props) { super(props); @@ -57,38 +79,38 @@ class BlockDropZone extends Component { } onDrop (event, position) { - if (! event.dataTransfer) { - return; - } - - let clientId, type, rootClientId, fromIndex, attributes; + const { rootClientId: dstRootClientId, clientId: dstClientId, index: dstIndex, getClientIdsOfDescendants } = this.props; + // GUTENBERG JS - get attributes as well + const { srcRootClientId, srcClientId, srcIndex, type, attributes } = parseDropEvent(event); + + const isBlockDropType = dropType => dropType === 'block'; + const isSameLevel = (srcRoot, dstRoot) => { + // Note that rootClientId of top-level blocks will be undefined OR a void string, + // so we also need to account for that case separately. + return (srcRoot === dstRoot) || (! srcRoot === true && ! dstRoot === true); + }; + const isSameBlock = (src, dst) => src === dst; + const isSrcBlockAnAncestorOfDstBlock = (src, dst) => getClientIdsOfDescendants([ src ]).some(id => id === dst); - try { - // GUTENBERG JS - receive attributes too - ({ clientId, type, rootClientId, fromIndex, attributes } = JSON.parse(event.dataTransfer.getData('text'))); - } - catch (err) { + if (! isBlockDropType(type) || + isSameBlock(srcClientId, dstClientId) || + isSrcBlockAnAncestorOfDstBlock(srcClientId, dstClientId)) { return; } - if (type !== 'block') { - return; - } - const { index } = this.props; const positionIndex = this.getInsertIndex(position); + // If the block is kept at the same level and moved downwards, + // subtract to account for blocks shifting upward to occupy its old position. + const insertIndex = dstIndex && srcIndex < dstIndex && isSameLevel(srcRootClientId, dstRootClientId) ? positionIndex - 1 : positionIndex; - // If the block is kept at the same level and moved downwards, subtract - // to account for blocks shifting upward to occupy its old position. - const insertIndex = index && fromIndex < index && rootClientId === this.props.rootClientId ? positionIndex - 1 : positionIndex; - - // check blocks and insert them + // check attributes: if they exist update block instead of move if (attributes) { // GUTENBERG JS - update existing block with new attributes // this.props.insertBlocks(blocks, insertIndex); - this.props.updateBlockAttributes(this.props.clientId, attributes); + this.props.updateBlockAttributes(dstClientId, attributes); } else { - this.props.moveBlockToPosition(clientId, rootClientId, insertIndex); + this.props.moveBlockToPosition(srcClientId, srcRootClientId, insertIndex); } } @@ -121,7 +143,7 @@ export default compose( } = dispatch('core/editor'); return { - insertBlocks (blocks, insertIndex) { + insertBlocks (blocks, index) { const { rootClientId, layout } = ownProps; if (layout) { @@ -134,21 +156,22 @@ export default compose( )); } - insertBlocks(blocks, insertIndex, rootClientId); + insertBlocks(blocks, index, rootClientId); }, updateBlockAttributes (...args) { updateBlockAttributes(...args); }, - moveBlockToPosition (clientId, fromRootClientId, index) { - const { rootClientId, layout } = ownProps; - moveBlockToPosition(clientId, fromRootClientId, rootClientId, layout, index); + moveBlockToPosition (srcClientId, srcRootClientId, dstIndex) { + const { rootClientId: dstRootClientId, layout } = ownProps; + moveBlockToPosition(srcClientId, srcRootClientId, dstRootClientId, layout, dstIndex); }, }; }), withSelect((select, { rootClientId }) => { - const { getTemplateLock } = select('core/editor'); + const { getClientIdsOfDescendants, getTemplateLock } = select('core/editor'); return { isLocked: !! getTemplateLock(rootClientId), + getClientIdsOfDescendants, }; }) )(BlockDropZone); From ed66a7add8dd7737476ef26358d4ae93cc47db33 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 16:16:29 +0100 Subject: [PATCH 18/27] feat: Update PostSavedState component --- .../editor/build-module/components/post-saved-state/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/js/gutenberg-overrides/packages/editor/build-module/components/post-saved-state/index.js b/src/js/gutenberg-overrides/packages/editor/build-module/components/post-saved-state/index.js index d531066..1092ec4 100644 --- a/src/js/gutenberg-overrides/packages/editor/build-module/components/post-saved-state/index.js +++ b/src/js/gutenberg-overrides/packages/editor/build-module/components/post-saved-state/index.js @@ -3,6 +3,7 @@ */ import { withSelect, withDispatch } from '@wordpress/data'; import { ifCondition, withSafeTimeout, compose } from '@wordpress/compose'; +import { withViewportMatch } from '@wordpress/viewport'; import * as others from 'gutenberg/packages/editor/build-module/components/post-saved-state?source=node_modules'; @@ -19,6 +20,7 @@ export default compose([ isEditedPostSaveable, getCurrentPost, isAutosavingPost, + getEditedPostAttribute, // GUTENBERG JS getEditorSettings, } = select('core/editor'); @@ -35,6 +37,7 @@ export default compose([ isSaving: forceIsSaving || isSavingPost(), isSaveable: isEditedPostSaveable(), isAutosaving: isAutosavingPost(), + isPending: 'pending' === getEditedPostAttribute('status'), // GUTENBERG JS canSave, }; @@ -43,6 +46,7 @@ export default compose([ onSave: dispatch('core/editor').savePost, })), withSafeTimeout, + withViewportMatch({ isLargeViewport: 'medium' }), // GUTENBERG JS // added the ifCondition to enable/disable // the save button according 'canSave' setting From 05b183f671d5632c2f071c8a32e72c7f57abb75d Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 16:23:07 +0100 Subject: [PATCH 19/27] feat: Remove block-labry style imports docs: Update readme file --- README.md | 26 +++++++++++++++++++++++--- src/js/index.js | 5 ----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 296963f..92cb19a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ We made [Gutenberg](https://github.com/Wordpress/gutenberg) editor a little more Gutenberg editor can **be easly included in your apps** with this [package](https://github.com/front/gutenberg-js). Also you can customize blocks menu panels, blocks categories, document panels and more! -This package is based on [Gutenberg v3.9.0](https://github.com/WordPress/gutenberg/releases/tag/v3.9.0). +This package is based on [Gutenberg v4.1.0](https://github.com/WordPress/gutenberg/releases/tag/v4.1.0). ## Table of contents @@ -32,13 +32,14 @@ This package is based on [Gutenberg v3.9.0](https://github.com/WordPress/gutenbe * [Custom blocks](#custom-blocks) * [Creating and Registering](#creating-and-registering) * [Sharing](#sharing) +* [Development](#development) ## Installation **gutenberg-js** is available through npm. ```sh -npm install @frontkom/gutenberg-js +$ npm install @frontkom/gutenberg-js ``` [↑ Go up to Table of contents](#table-of-contents) @@ -263,7 +264,8 @@ import '@frontkom/gutenberg-js/build/css/components/style.css'; import '@frontkom/gutenberg-js/build/css/nux/style.css'; import '@frontkom/gutenberg-js/build/css/editor/style.css'; import '@frontkom/gutenberg-js/build/css/block-library/theme.css'; -import '@frontkom/gutenberg-js/build/css/block-library/edit-blocks.css'; +import '@frontkom/gutenberg-js/build/css/block-library/edir.css'; +import '@frontkom/gutenberg-js/build/css/edit-post/style.css'; import '@frontkom/gutenberg-js/build/css/style.css'; // DOM element id where editor will be displayed @@ -566,3 +568,21 @@ An easy way to share a custom block is to publish the block as a npm package. Here is an example of a custom block npm package, the [Hero Section](https://github.com/front/g-hero-section). [↑ Go up to Table of contents](#table-of-contents) + +## Development + +### Gutenberg and install script + +[...] + +### Overrides + +[...] + +### Publising + +```sh +$ npm run deploy +``` + +[↑ Go up to Table of contents](#table-of-contents) diff --git a/src/js/index.js b/src/js/index.js index 224ed2a..f6bf6b1 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -21,11 +21,6 @@ import * as hooks from '@wordpress/hooks'; import * as i18n from '@wordpress/i18n'; import * as plugins from '@wordpress/plugins'; -// and styles -import 'gutenberg/block-library/editor.scss'; -import 'gutenberg/block-library/theme.scss'; -import 'gutenberg/block-library/style.scss'; - // Adding modules to wp global window.wp.blockLibrary = blockLibrary; window.wp.blocks = blocks; From 9fd0b5cd9c1e7118743314dc65ccf544e0142978 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Thu, 25 Oct 2018 16:37:51 +0100 Subject: [PATCH 20/27] feat: Remove unnecessary overrides --- .../edit-post/CHANGELOG.md | 25 --- .../sidebar/document-sidebar/index.js | 69 -------- src/js/gutenberg-overrides/edit-post/index.js | 2 - .../packages/block-library/CHANGELOG.md | 6 +- .../packages/editor/CHANGELOG.md | 6 + .../editor/build-module/store/actions.js | 25 --- .../editor/build-module/utils/CHANGELOG.md | 7 - .../utils/media-upload/media-upload.js | 160 ------------------ 8 files changed, 7 insertions(+), 293 deletions(-) delete mode 100644 src/js/gutenberg-overrides/edit-post/CHANGELOG.md delete mode 100644 src/js/gutenberg-overrides/edit-post/components/sidebar/document-sidebar/index.js delete mode 100644 src/js/gutenberg-overrides/edit-post/index.js delete mode 100644 src/js/gutenberg-overrides/packages/editor/build-module/store/actions.js delete mode 100644 src/js/gutenberg-overrides/packages/editor/build-module/utils/CHANGELOG.md delete mode 100644 src/js/gutenberg-overrides/packages/editor/build-module/utils/media-upload/media-upload.js diff --git a/src/js/gutenberg-overrides/edit-post/CHANGELOG.md b/src/js/gutenberg-overrides/edit-post/CHANGELOG.md deleted file mode 100644 index 717debf..0000000 --- a/src/js/gutenberg-overrides/edit-post/CHANGELOG.md +++ /dev/null @@ -1,25 +0,0 @@ -# edit-post changelog - -## 1.2.1 2018-07-30 - -### Changed - -- **MediaLibrary**: show thumbnails instead of original images [edit-post/hooks/components/media-upload/index.js](https://github.com/front/gutenberg-js/blob/v1.2.1/src/js/gutenberg-overrides/edit-post/hooks/components/media-upload/index.js)) - -## 0.1.0 2018-07-19 - -### Changed - -- **MediaUpload** component and implement the Media Library with existing images [edit-post/hooks/components/media-upload/index.js](https://github.com/front/gutenberg-js/blob/v0.1.0/src/js/gutenberg-overrides/edit-post/hooks/components/media-upload/index.js)) - -## 0.0.1 2018-07-11 - -### Added - -- **MediaUpload** override [edit-post/hooks/components/media-upload/index.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/edit-post/hooks/components/media-upload/index.js)) - -- `OPEN_GENERAL_SIDEBAR` and `CLOSE_GENERAL_SIDEBAR` effects [edit-post/store/effects.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/edit-post/store/effects.js)) - -- **PluginDocumentSidebarPanel** component and **DocumentSidebar** override to included *PluginDocumentSidebarPanel* ([edit-post/components/sidebar/document-sidebar/index.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/edit-post/components/sidebar/document-sidebar/index.js)) - -- Exported the **PluginDocumentSidebarPanel** component (make it accessible from outside) ([edit-post/index.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/edit-post/index.js)) diff --git a/src/js/gutenberg-overrides/edit-post/components/sidebar/document-sidebar/index.js b/src/js/gutenberg-overrides/edit-post/components/sidebar/document-sidebar/index.js deleted file mode 100644 index 6a322db..0000000 --- a/src/js/gutenberg-overrides/edit-post/components/sidebar/document-sidebar/index.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * External Dependencies - */ -import React from 'react'; - -/** - * WordPress dependencies - */ -import { createSlotFill, PanelBody, Panel } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; - -/** - * Internal Dependencies - */ -import PostStatus from '../post-status'; -import PostExcerpt from '../post-excerpt'; -import PostTaxonomies from '../post-taxonomies'; -import FeaturedImage from '../featured-image'; -import DiscussionPanel from '../discussion-panel'; -import LastRevision from '../last-revision'; -import PageAttributes from '../page-attributes'; -import MetaBoxes from '../../meta-boxes'; -import SettingsHeader from '../settings-header'; -import Sidebar from '../'; - -export const { Fill, Slot } = createSlotFill('PluginDocumentSidebarPanel'); - -// Plugin to add panels to document sidebar -const PluginDocumentSidebarPanel = ({ children, className, title, initialOpen = false, isOpened, onTogglePanel }) => ( - - - { children } - - -); - -PluginDocumentSidebarPanel.Slot = Slot; - -export { PluginDocumentSidebarPanel }; - -const SIDEBAR_NAME = 'edit-post/document'; - -const DocumentSidebar = () => ( - - - - - - - - - - - - - - -); - -export default DocumentSidebar; diff --git a/src/js/gutenberg-overrides/edit-post/index.js b/src/js/gutenberg-overrides/edit-post/index.js deleted file mode 100644 index 2182307..0000000 --- a/src/js/gutenberg-overrides/edit-post/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { PluginDocumentSidebarPanel } from './components/sidebar/document-sidebar'; -export * from 'gutenberg/edit-post?source=node_modules'; diff --git a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md index 0d1d7ed..5e35a75 100644 --- a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md @@ -4,11 +4,7 @@ ### Changed -- 'cover-image' to 'cover' block ([packages/block-libary/build-module/cover](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/cover)) - -- 'gallery' block ([packages/block-libary/build-module/gallery/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/gallery/edit.js)) and ([packages/block-libary/build-module/gallery/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/gallery/gallery-image.js)) - -- 'image' block ([packages/block-libary/build-module/image/edit.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-libary/build-module/image/edit.js)) +- 'cover-image' to 'cover' ([packages/block-library/build-module/cover](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-library/build-module/cover)) ## 2.0.0 2018-08 diff --git a/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md b/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md index f3dcf87..fb06fef 100644 --- a/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/editor/CHANGELOG.md @@ -6,6 +6,10 @@ - BlockListBlock override +- `insertDefaultBlock` action override + +- mediaUpload override + ### Added - `addQueryArgs` to 'Manage All Reusable Blocks' link (Inserter Menu) ([packages/editor/build-module/components/inserter/menu.js](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/editor/build-module/components/inserter/menu.js)) @@ -59,3 +63,5 @@ - `onDrop` override in order to accept blocks from PostItemDraggable ([editor/components/block-drop-zone/index.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/editor/components/block-drop-zone/index.js)) - `INSERTER_UTILITY_HIGH`, `INSERTER_UTILITY_MEDIUM` and `INSERTER_UTILITY_LOW` overrides with `INSERTER_UTILITY_NONE` so there is no different levels of utility and consequently no **Most Used** panel ([editor/store/selectors.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/editor/store/selectors.js)) + +- `data` property to `mediaObject` and use `get` function to obtain image `title` in `mediaUpload` function ([utils/mediaupload.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/utils/mediaupload.js)) diff --git a/src/js/gutenberg-overrides/packages/editor/build-module/store/actions.js b/src/js/gutenberg-overrides/packages/editor/build-module/store/actions.js deleted file mode 100644 index b648893..0000000 --- a/src/js/gutenberg-overrides/packages/editor/build-module/store/actions.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * WordPress dependencies - */ -import { - getDefaultBlockName, - createBlock, -} from '@wordpress/blocks'; - -import * as others from 'gutenberg/packages/editor/build-module/store/actions?source=node_modules'; - -const { insertBlock } = others; - -// Override 'insertDefaultBlock' action in order to could set -// Section as default block -others.insertDefaultBlock = (attributes, rootClientId, index) => { - const blockName = rootClientId === undefined ? getDefaultBlockName() : 'core/paragraph'; - const block = createBlock(blockName, attributes); - - return { - ...insertBlock(block, index, rootClientId), - isProvisional: blockName === 'core/paragraph', - }; -}; - -export * from 'gutenberg/packages/editor/build-module/store/actions?source=node_modules'; diff --git a/src/js/gutenberg-overrides/packages/editor/build-module/utils/CHANGELOG.md b/src/js/gutenberg-overrides/packages/editor/build-module/utils/CHANGELOG.md deleted file mode 100644 index dd62af5..0000000 --- a/src/js/gutenberg-overrides/packages/editor/build-module/utils/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# utils changelog - -## 0.0.1 2018-07-11 - -### Added - -- `data` property to `mediaObject` and use `get` function to obtain image `title` in `mediaUpload` function ([utils/mediaupload.js](https://github.com/front/gutenberg-js/blob/v0.0.1/src/js/gutenberg-overrides/utils/mediaupload.js)) diff --git a/src/js/gutenberg-overrides/packages/editor/build-module/utils/media-upload/media-upload.js b/src/js/gutenberg-overrides/packages/editor/build-module/utils/media-upload/media-upload.js deleted file mode 100644 index a18c8f4..0000000 --- a/src/js/gutenberg-overrides/packages/editor/build-module/utils/media-upload/media-upload.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * External Dependencies - */ -import React from 'react'; -import { compact, forEach, get, has, includes, noop, startsWith } from 'lodash'; - -/** - * WordPress dependencies - */ -import apiFetch from '@wordpress/api-fetch'; -import { __, sprintf } from '@wordpress/i18n'; - -import * as others from 'gutenberg/packages/editor/build-module/utils/media-upload/media-upload?source=node_modules'; - -const { getMimeTypesArray } = others; - -// required local function -function createMediaFromFile (file, additionalData) { - // Create upload payload - const data = new window.FormData(); - data.append('file', file, file.name || file.type.replace('/', '.')); - data.append('title', file.name ? file.name.replace(/\.[^.]+$/, '') : file.type.replace('/', '.')); - forEach(additionalData, ((value, key) => data.append(key, value))); - return apiFetch({ - path: '/wp/v2/media', - body: data, - method: 'POST', - }); -} - -// Added data attribute -others.mediaUpload = ({ - allowedType, - additionalData = {}, - filesList, - maxUploadFileSize, - onError = noop, - onFileChange, - allowedMimeTypes = null, -}) => { - // Cast filesList to array - const files = [ ...filesList ]; - - const filesSet = []; - const setAndUpdateFiles = (idx, value) => { - filesSet[ idx ] = value; - onFileChange(compact(filesSet)); - }; - - // Allowed type specified by consumer - const isAllowedType = fileType => { - return (allowedType === '*') || startsWith(fileType, `${allowedType}/`); - }; - - // Allowed types for the current WP_User - const allowedMimeTypesForUser = getMimeTypesArray(allowedMimeTypes); - const isAllowedMimeTypeForUser = fileType => { - return includes(allowedMimeTypesForUser, fileType); - }; - - // Build the error message including the filename - const triggerError = error => { - error.message = [ - { error.file.name }, - ': ', - error.message, - ]; - - onError(error); - }; - - files.forEach((mediaFile, idx) => { - // verify if user is allowed to upload this mime type - if (allowedMimeTypesForUser && ! isAllowedMimeTypeForUser(mediaFile.type)) { - triggerError({ - code: 'MIME_TYPE_NOT_ALLOWED_FOR_USER', - message: __('Sorry, this file type is not permitted for security reasons.'), - file: mediaFile, - }); - return; - } - - // Check if the block supports this mime type - if (! isAllowedType(mediaFile.type)) { - triggerError({ - code: 'MIME_TYPE_NOT_SUPPORTED', - message: __('Sorry, this file type is not supported here.'), - file: mediaFile, - }); - return; - } - - // verify if file is greater than the maximum file upload size allowed for the site. - if (maxUploadFileSize && mediaFile.size > maxUploadFileSize) { - triggerError({ - code: 'SIZE_ABOVE_LIMIT', - message: __('This file exceeds the maximum upload size for this site.'), - file: mediaFile, - }); - return; - } - - // Don't allow empty files to be uploaded. - if (mediaFile.size <= 0) { - triggerError({ - code: 'EMPTY_FILE', - message: __('This file is empty.'), - file: mediaFile, - }); - return; - } - - // Set temporary URL to create placeholder media file, this is replaced - // with final file from media gallery when upload is `done` below - filesSet.push({ url: window.URL.createObjectURL(mediaFile) }); - onFileChange(filesSet); - - return createMediaFromFile(mediaFile, additionalData) - .then(savedMedia => { - const mediaObject = { - alt: savedMedia.alt_text, - caption: get(savedMedia, [ 'caption', 'raw' ], ''), - id: savedMedia.id, - link: savedMedia.link, - title: savedMedia.title.raw, - url: savedMedia.source_url, - mediaDetails: {}, - // GUTENBERG JS - // added data property to handle with image data attributes - data: savedMedia.data, - }; - if (has(savedMedia, [ 'media_details', 'sizes' ])) { - mediaObject.mediaDetails.sizes = get(savedMedia, [ 'media_details', 'sizes' ], {}); - } - setAndUpdateFiles(idx, mediaObject); - }) - .catch(error => { - // Reset to empty on failure. - setAndUpdateFiles(idx, null); - let message; - if (has(error, [ 'message' ])) { - message = get(error, [ 'message' ]); - } - else { - message = sprintf( - // translators: %s: file name - __('Error while uploading file %s to the media library.'), - mediaFile.name - ); - } - onError({ - code: 'GENERAL', - message, - file: mediaFile, - }); - }); - }); -}; - -export * from 'gutenberg/packages/editor/build-module/utils/media-upload/media-upload?source=node_modules'; From 1c348ef0d055d1f2b3caa7415e041e4321eddeab Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Wed, 31 Oct 2018 12:00:40 +0000 Subject: [PATCH 21/27] feat: Remove unused overrides and deprecated stuff --- .../packages/components/build-module/index.js | 3 - .../components/block-drop-zone/index.js | 177 ------------------ src/scss/_block-drop-zone.scss | 14 -- src/scss/_gbcolors.scss | 89 --------- 4 files changed, 283 deletions(-) delete mode 100644 src/js/gutenberg-overrides/packages/components/build-module/index.js delete mode 100644 src/js/gutenberg-overrides/packages/editor/build-module/components/block-drop-zone/index.js delete mode 100644 src/scss/_block-drop-zone.scss delete mode 100644 src/scss/_gbcolors.scss diff --git a/src/js/gutenberg-overrides/packages/components/build-module/index.js b/src/js/gutenberg-overrides/packages/components/build-module/index.js deleted file mode 100644 index 8c32f7b..0000000 --- a/src/js/gutenberg-overrides/packages/components/build-module/index.js +++ /dev/null @@ -1,3 +0,0 @@ - -export { default as CategorySelect } from './query-controls/category-select.js'; -export * from 'gutenberg/packages/components/build-module/index?source=node_modules'; diff --git a/src/js/gutenberg-overrides/packages/editor/build-module/components/block-drop-zone/index.js b/src/js/gutenberg-overrides/packages/editor/build-module/components/block-drop-zone/index.js deleted file mode 100644 index 7519b3d..0000000 --- a/src/js/gutenberg-overrides/packages/editor/build-module/components/block-drop-zone/index.js +++ /dev/null @@ -1,177 +0,0 @@ -/** - * External Dependencies - */ -import React from 'react'; -import { castArray } from 'lodash'; -import classnames from 'classnames'; - -/** - * WordPress dependencies - */ -import { DropZone } from '@wordpress/components'; -import { - rawHandler, - cloneBlock, - getBlockTransforms, - findTransform, -} from '@wordpress/blocks'; -import { Component } from '@wordpress/element'; -import { withDispatch, withSelect } from '@wordpress/data'; -import { compose } from '@wordpress/compose'; - -const parseDropEvent = event => { - let result = { - srcRootClientId: null, - srcClientId: null, - srcIndex: null, - type: null, - }; - - if (! event.dataTransfer) { - return result; - } - - try { - result = Object.assign(result, JSON.parse(event.dataTransfer.getData('text'))); - } - catch (err) { - return result; - } - - return result; -}; - -class BlockDropZone extends Component { - constructor (props) { - super(props); - - this.onFilesDrop = this.onFilesDrop.bind(this); - this.onHTMLDrop = this.onHTMLDrop.bind(this); - this.onDrop = this.onDrop.bind(this); - } - - getInsertIndex (position) { - const { index } = this.props; - if (index !== undefined) { - return position.y === 'top' ? index : index + 1; - } - } - - onFilesDrop (files, position) { - const transformation = findTransform( - getBlockTransforms('from'), - transform => transform.type === 'files' && transform.isMatch(files) - ); - - if (transformation) { - const insertIndex = this.getInsertIndex(position); - const blocks = transformation.transform(files, this.props.updateBlockAttributes); - this.props.insertBlocks(blocks, insertIndex); - } - } - - onHTMLDrop (HTML, position) { - const blocks = rawHandler({ HTML, mode: 'BLOCKS' }); - - if (blocks.length) { - this.props.insertBlocks(blocks, this.getInsertIndex(position)); - } - } - - onDrop (event, position) { - const { rootClientId: dstRootClientId, clientId: dstClientId, index: dstIndex, getClientIdsOfDescendants } = this.props; - // GUTENBERG JS - get attributes as well - const { srcRootClientId, srcClientId, srcIndex, type, attributes } = parseDropEvent(event); - - const isBlockDropType = dropType => dropType === 'block'; - const isSameLevel = (srcRoot, dstRoot) => { - // Note that rootClientId of top-level blocks will be undefined OR a void string, - // so we also need to account for that case separately. - return (srcRoot === dstRoot) || (! srcRoot === true && ! dstRoot === true); - }; - const isSameBlock = (src, dst) => src === dst; - const isSrcBlockAnAncestorOfDstBlock = (src, dst) => getClientIdsOfDescendants([ src ]).some(id => id === dst); - - if (! isBlockDropType(type) || - isSameBlock(srcClientId, dstClientId) || - isSrcBlockAnAncestorOfDstBlock(srcClientId, dstClientId)) { - return; - } - - const positionIndex = this.getInsertIndex(position); - // If the block is kept at the same level and moved downwards, - // subtract to account for blocks shifting upward to occupy its old position. - const insertIndex = dstIndex && srcIndex < dstIndex && isSameLevel(srcRootClientId, dstRootClientId) ? positionIndex - 1 : positionIndex; - - // check attributes: if they exist update block instead of move - if (attributes) { - // GUTENBERG JS - update existing block with new attributes - // this.props.insertBlocks(blocks, insertIndex); - this.props.updateBlockAttributes(dstClientId, attributes); - } - else { - this.props.moveBlockToPosition(srcClientId, srcRootClientId, insertIndex); - } - } - - render () { - const { isLocked, index } = this.props; - if (isLocked) { - return null; - } - const isAppender = index === undefined; - - return ( - - ); - } -} - -export default compose( - withDispatch((dispatch, ownProps) => { - const { - insertBlocks, - updateBlockAttributes, - moveBlockToPosition, - } = dispatch('core/editor'); - - return { - insertBlocks (blocks, index) { - const { rootClientId, layout } = ownProps; - - if (layout) { - // A block's transform function may return a single - // transformed block or an array of blocks, so ensure - // to first coerce to an array before mapping to inject - // the layout attribute. - blocks = castArray(blocks).map(block => ( - cloneBlock(block, { layout }) - )); - } - - insertBlocks(blocks, index, rootClientId); - }, - updateBlockAttributes (...args) { - updateBlockAttributes(...args); - }, - moveBlockToPosition (srcClientId, srcRootClientId, dstIndex) { - const { rootClientId: dstRootClientId, layout } = ownProps; - moveBlockToPosition(srcClientId, srcRootClientId, dstRootClientId, layout, dstIndex); - }, - }; - }), - withSelect((select, { rootClientId }) => { - const { getClientIdsOfDescendants, getTemplateLock } = select('core/editor'); - return { - isLocked: !! getTemplateLock(rootClientId), - getClientIdsOfDescendants, - }; - }) -)(BlockDropZone); diff --git a/src/scss/_block-drop-zone.scss b/src/scss/_block-drop-zone.scss deleted file mode 100644 index d685afc..0000000 --- a/src/scss/_block-drop-zone.scss +++ /dev/null @@ -1,14 +0,0 @@ -// Dropzones -.editor-block-drop-zone { - &.is-dragging-default { - .components-drop-zone__content { - display: flex!important; - flex-direction: column; - justify-content: center; - background-color: rgba(#0085ba, 0.6); - transform: none!important; - top: 0; - bottom: 0; - } - } -} diff --git a/src/scss/_gbcolors.scss b/src/scss/_gbcolors.scss deleted file mode 100644 index 337bbe6..0000000 --- a/src/scss/_gbcolors.scss +++ /dev/null @@ -1,89 +0,0 @@ -// temp solution to override colors of template - -.has-pale-pink-background-color { - background-color: #f78da7!important; -} - -.has-vivid-red-background-color { - background-color: #cf2e2e!important; -} - -.has-luminous-vivid-orange-background-color { - background-color: #ff6900!important; -} - -.has-luminous-vivid-amber-background-color { - background-color: #fcb900!important; -} - -.has-light-green-cyan-background-color { - background-color: #7bdcb5!important; -} - -.has-vivid-green-cyan-background-color { - background-color: #00d084!important; -} - -.has-pale-cyan-blue-background-color { - background-color: #8ed1fc!important; -} - -.has-vivid-cyan-blue-background-color { - background-color: #0693e3!important; -} - -.has-very-light-gray-background-color { - background-color: #eeeeee!important; -} - -.has-cyan-bluish-gray-background-color { - background-color: #abb8c3!important; -} - -.has-very-dark-gray-background-color { - background-color: #313131!important; -} - -.has-pale-pink-color { - color: #f78da7!important; -} - -.has-vivid-red-color { - color: #cf2e2e!important; -} - -.has-luminous-vivid-orange-color { - color: #ff6900!important; -} - -.has-luminous-vivid-amber-color { - color: #fcb900!important; -} - -.has-light-green-cyan-color { - color: #7bdcb5!important; -} - -.has-vivid-green-cyan-color { - color: #00d084!important; -} - -.has-pale-cyan-blue-color { - color: #8ed1fc!important; -} - -.has-vivid-cyan-blue-color { - color: #0693e3!important; -} - -.has-very-light-gray-color { - color: #eeeeee!important; -} - -.has-cyan-bluish-gray-color { - color: #abb8c3!important; -} - -.has-very-dark-gray-color { - color: #313131!important; -} From ae82a7a9e29b3f1b8cb5ffa42ac7f8e49016e1ba Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Wed, 31 Oct 2018 12:02:29 +0000 Subject: [PATCH 22/27] feat: Upgarde gutenberg to 4.2.0-rc.1 and update package.json and webpack config --- package.json | 5 +- scripts/install.sh | 2 +- webpack.config.js | 146 +++++++++++---------------------------------- 3 files changed, 37 insertions(+), 116 deletions(-) diff --git a/package.json b/package.json index d48b06d..fd76d34 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "WYSIWYG" ], "dependencies": { + "react-dates": "^18.1.1", "tinymce": "4.8.0" }, "devDependencies": { @@ -61,9 +62,7 @@ "raw-loader": "0.5.1", "sass-loader": "6.0.7", "webpack": "4.8.3", - "webpack-cli": "2.1.3", - "webpack-livereload-plugin": "2.1.1", - "webpack-rtl-plugin": "github:yoavf/webpack-rtl-plugin#develop" + "webpack-cli": "2.1.3" }, "private": false } diff --git a/scripts/install.sh b/scripts/install.sh index 4845296..0c92ca8 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -13,7 +13,7 @@ git clone https://github.com/WordPress/gutenberg.git cd gutenberg # checkout to version we want -git checkout tags/v4.1.0 +git checkout tags/v4.2.0-rc.1 # remove git references # GUTENBERG HAS A SUBMODULE NOW diff --git a/webpack.config.js b/webpack.config.js index b73ec1b..e9600d5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,54 +2,18 @@ * External dependencies */ const ExtractTextPlugin = require('extract-text-webpack-plugin'); -const WebpackRTLPlugin = require('webpack-rtl-plugin'); -const LiveReloadPlugin = require('webpack-livereload-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const postcss = require('postcss'); -const { get } = require('lodash'); -const { basename, resolve } = require('path'); +const { resolve } = require('path'); /** * Gutenberg-js dependencies */ // const PostCssWrapper = require('postcss-wrapper-loader'); -const StringReplacePlugin = require('string-replace-webpack-plugin'); +// const StringReplacePlugin = require('string-replace-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); -/** - * WordPress dependencies - */ -const CustomTemplatedPathPlugin = require('./node_modules/gutenberg/packages/custom-templated-path-webpack-plugin'); -const LibraryExportDefaultPlugin = require('./node_modules/gutenberg/packages/library-export-default-webpack-plugin'); - -// Main CSS loader for everything but blocks.. -const mainCSSExtractTextPlugin = new ExtractTextPlugin({ - filename: './css/style.css', -}); - -// Configuration for the ExtractTextPlugin. -const extractConfig = { - use: [ - { loader: 'raw-loader' }, - { - loader: 'postcss-loader', - options: { - plugins: require('./node_modules/gutenberg/bin/packages/post-css-config'), - }, - }, - { - loader: 'sass-loader', - query: { - includePaths: [ './node_modules/gutenberg/assets/stylesheets' ], - data: '@import "colors"; @import "breakpoints"; @import "variables"; @import "mixins"; @import "animations"; @import "z-index";', - outputStyle: 'production' === process.env.NODE_ENV ? - 'compressed' : 'nested', - }, - }, - ], -}; - /** * Given a string, returns a new string with dash separators converedd to * camel-case equivalent. This is not as aggressive as `_.camelCase` in @@ -67,11 +31,6 @@ function camelCaseDash (string) { ); } -const entryPointNames = [ - 'components', - // 'block-library', -]; - const gutenbergPackages = [ 'a11y', // 'api-fetch', // global @@ -94,12 +53,14 @@ const gutenbergPackages = [ 'editor', 'element', 'escape-html', + 'format-library', 'hooks', 'html-entities', 'i18n', 'is-shallow-equal', 'keycodes', 'list-reusable-blocks', + 'notices', 'nux', 'plugins', 'redux-routine', @@ -111,39 +72,37 @@ const gutenbergPackages = [ 'wordcount', ]; -const coreGlobals = [ - 'api-fetch', - 'url', -]; - -const externals = {}; +const externals = { + react: 'React', + 'react-dom': 'ReactDOM', + moment: 'moment', + jquery: 'jQuery', + lodash: 'lodash', + 'lodash-es': 'lodash', +}; const alias = {}; -entryPointNames.forEach(name => { - alias[ `@wordpress/${name}` ] = resolve(__dirname, 'node_modules/gutenberg', name); -}); - gutenbergPackages.forEach(name => { alias[ `@wordpress/${name}` ] = resolve(__dirname, 'node_modules/gutenberg/packages', name); }); [ - ...coreGlobals, + 'api-fetch', + 'url', ].forEach(name => { externals[ `@wordpress/${name}` ] = { this: [ 'wp', camelCaseDash(name) ], }; }); -const config = { +module.exports = { mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', - + devtool: 'source-map', entry: './src/js/index.js', output: { filename: 'js/gutenberg-js.js', path: resolve(__dirname, 'build'), - // library: ['wp'], libraryTarget: 'this', }, externals, @@ -180,7 +139,7 @@ const config = { }, ], }, - { + /* { test: /editor\.s?css$/, include: [ /block-library/, @@ -200,59 +159,32 @@ const config = { ...extractConfig.use, ], }), - }, + },*/ { test: /\.s?css$/, - use: mainCSSExtractTextPlugin.extract(extractConfig), + use: ExtractTextPlugin.extract({ + fallback: 'style-loader', // creates style nodes from JS strings + use: [ + { loader: 'css-loader' }, // translates CSS into CommonJS + { loader: 'sass-loader' }, // compiles Sass to CSS + ], + }), }, ], }, plugins: [ - mainCSSExtractTextPlugin, + new ExtractTextPlugin('./css/style.css'), // wrapping editor style with .gutenberg__editor class // new PostCssWrapper('./css/block-library/edit-blocks.css', '.gutenberg__editor'), - new StringReplacePlugin(), + // new StringReplacePlugin(), new CleanWebpackPlugin(['build']), - // Create RTL files with a -rtl suffix - new WebpackRTLPlugin({ - suffix: '-rtl', - minify: process.env.NODE_ENV === 'production' ? { safe: true } : false, - }), - new CustomTemplatedPathPlugin({ - basename (path, data) { - let rawRequest; - - const entryModule = get(data, [ 'chunk', 'entryModule' ], {}); - switch (entryModule.type) { - case 'javascript/auto': - rawRequest = entryModule.rawRequest; - break; - - case 'javascript/esm': - rawRequest = entryModule.rootModule.rawRequest; - break; - } - - if (rawRequest) { - return basename(rawRequest); - } - - return path; - }, - }), - new LibraryExportDefaultPlugin([ - 'api-fetch', - 'deprecated', - 'dom-ready', - 'redux-routine', - ].map(camelCaseDash)), - new CopyWebpackPlugin( - gutenbergPackages.map(packageName => ({ - from: `./node_modules/gutenberg/packages/${packageName}/build-style/*.css`, - to: `./css/${packageName}/`, + new CopyWebpackPlugin([ + { + from: `./node_modules/gutenberg/packages/block-library/build-style/style.css`, + to: `./css/block-library/`, flatten: true, transform: content => { - if (config.mode === 'production') { + if (process.env.NODE_ENV === 'production') { return postcss([ require('cssnano')({ preset: 'default', @@ -263,20 +195,10 @@ const config = { } return content; }, - })) - ), + }, + ]), ], stats: { children: false, }, }; - -if (config.mode !== 'production') { - config.devtool = process.env.SOURCEMAP || 'source-map'; -} - -if (config.mode === 'development') { - config.plugins.push(new LiveReloadPlugin({ port: process.env.GUTENBERG_LIVE_RELOAD_PORT || 35729 })); -} - -module.exports = config; From 47bf4dced7ef5b98869c2c5b236ab9c914a2dca6 Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Wed, 31 Oct 2018 12:03:56 +0000 Subject: [PATCH 23/27] feat: Sort modules in index feat: Remove wp-init and add packages/apifetch, url and data feat: Add oldEditor --- src/js/index.js | 166 ++++++++++++++++++++++++++++------- src/js/oldEditor.js | 59 +++++++++++++ src/js/packages/api-fetch.js | 21 +++++ src/js/packages/data.js | 8 ++ src/js/packages/url.js | 6 ++ src/js/wp-init.js | 155 -------------------------------- src/scss/style.scss | 1 - 7 files changed, 226 insertions(+), 190 deletions(-) create mode 100644 src/js/oldEditor.js create mode 100644 src/js/packages/api-fetch.js create mode 100644 src/js/packages/data.js create mode 100644 src/js/packages/url.js delete mode 100644 src/js/wp-init.js diff --git a/src/js/index.js b/src/js/index.js index f6bf6b1..04f9d46 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -1,56 +1,154 @@ -/** - * Internal dependencies - */ -import './wp-init.js'; -import '../scss/style.scss'; - /** * WordPress dependencies */ -import * as blockLibrary from '@wordpress/block-library'; -import * as blocks from '@wordpress/blocks'; -import * as components from '@wordpress/components'; +import * as autop from '@wordpress/autop'; +import * as blob from '@wordpress/blob'; +import * as blockSerializationDefaultParser from '@wordpress/block-serialization-default-parser'; + +import * as escapeHtml from '@wordpress/escape-html'; +import * as element from '@wordpress/element'; +import * as isShallowEqual from '@wordpress/is-shallow-equal'; import * as compose from '@wordpress/compose'; -import * as coreData from '@wordpress/core-data'; +import * as hooks from '@wordpress/hooks'; +import deprecated from '@wordpress/deprecated'; +import * as reduxRoutine from '@wordpress/redux-routine'; + import * as data from '@wordpress/data'; +import './packages/data.js'; + +import * as dom from '@wordpress/dom'; +import * as i18n from '@wordpress/i18n'; +import * as shortcode from '@wordpress/shortcode'; +import * as blocks from '@wordpress/blocks'; import domReady from '@wordpress/dom-ready'; +import * as a11y from '@wordpress/a11y'; + +import * as url from './packages/url.js'; +import * as apiFetch from './packages/api-fetch.js'; + +import * as htmlEntities from '@wordpress/html-entities'; +import * as keycodes from '@wordpress/keycodes'; +import * as richText from '@wordpress/rich-text'; +import * as components from '@wordpress/components'; + +import * as coreData from '@wordpress/core-data'; + +import * as date from '@wordpress/date'; +import * as nux from '@wordpress/nux'; +import * as tokenList from '@wordpress/token-list'; +import * as viewport from '@wordpress/viewport'; +import * as wordcount from '@wordpress/wordcount'; + import * as editor from '@wordpress/editor'; -import * as editPost from '@wordpress/edit-post'; -import * as element from '@wordpress/element'; -import * as hooks from '@wordpress/hooks'; -import * as i18n from '@wordpress/i18n'; +import * as oldEditorFunctions from './oldEditor.js'; + import * as plugins from '@wordpress/plugins'; +import * as blockLibrary from '@wordpress/block-library'; +import * as editPost from '@wordpress/edit-post'; + +// Style +import 'gutenberg/packages/components/build-style/style.css'; +import 'gutenberg/packages/nux/build-style/style.css'; +import 'gutenberg/packages/editor/build-style/style.css'; +import 'gutenberg/packages/block-library/build-style/theme.css'; +import 'gutenberg/packages/block-library/build-style/editor.css'; +import 'gutenberg/packages/edit-post/build-style/style.css'; +import '../scss/style.scss'; -// Adding modules to wp global -window.wp.blockLibrary = blockLibrary; -window.wp.blocks = blocks; -window.wp.components = components; -window.wp.compose = compose; -window.wp.coreData = coreData; -window.wp.data = data; -window.wp.domReady = domReady; -window.wp.editor = { - ...window.wp.editor, +const oldEditor = { + ...oldEditorFunctions, ...editor, }; -window.wp.editPost = editPost; -window.wp.element = element; -window.wp.hooks = hooks; -window.wp.i18n = i18n; -window.wp.plugins = plugins; -export { - blockLibrary, - blocks, - components, +// Set global wp +window.wp = { + apiFetch, + url, + + autop, + blob, + blockSerializationDefaultParser, + escapeHtml, + element, + isShallowEqual, compose, - coreData, + hooks, + deprecated, + reduxRoutine, data, + dom, + i18n, + shortcode, + blocks, domReady, + a11y, + htmlEntities, + keycodes, + richText, + components, + coreData, + date, + nux, + tokenList, + viewport, + wordcount, editor, + oldEditor, + plugins, + blockLibrary, editPost, + // ...window.wp, +}; + +// User settings +window.userSettings = window.userSettings || { + secure: '', + time: 1234567, + uid: 1, +}; + +// postboxes +window.postboxes = window.postboxes || { + add_postbox_toggles: (page, args) => { + console.log('page', page); + console.log('args', args); + }, +}; + +export { + apiFetch, + url, + + autop, + blob, + blockSerializationDefaultParser, + escapeHtml, element, + isShallowEqual, + compose, hooks, + deprecated, + reduxRoutine, + data, + dom, i18n, + shortcode, + blocks, + domReady, + a11y, + htmlEntities, + keycodes, + richText, + components, + coreData, + date, + nux, + tokenList, + viewport, + wordcount, + editor, + oldEditor, plugins, + blockLibrary, + editPost, }; diff --git a/src/js/oldEditor.js b/src/js/oldEditor.js new file mode 100644 index 0000000..f6b1155 --- /dev/null +++ b/src/js/oldEditor.js @@ -0,0 +1,59 @@ +import jQuery from 'jquery'; +import tinymce from 'tinymce'; + +window.tinymce = window.tinymce || tinymce; + +export const initialize = (id, settings = { tinymce: true }) => { + const defaults = window.wp.editor.getDefaultSettings(); + const init = jQuery.extend({}, defaults.tinymce, settings.tinymce); + + init.selector = '#' + id; + + window.tinymce.init(init); + + if (! window.wpActiveEditor) { + window.wpActiveEditor = id; + } +}; + +export const autop = () => {}; + +export const getContent = id => { + const editor = window.tinymce.get(id); + + if (editor && ! editor.isHidden()) { + editor.save(); + } + + return jQuery('#' + id).val(); +}; + +export const remove = id => { + const mceInstance = window.tinymce.get(id); + + if (mceInstance) { + if (! mceInstance.isHidden()) { + mceInstance.save(); + } + + mceInstance.remove(); + } +}; + +export const removep = () => {}; + +export const getDefaultSettings = () => ({ + tinymce: { + indent: true, + keep_styles: false, + menubar: false, + plugins: 'charmap,colorpicker,hr,lists,media,paste,tabfocus,textcolor,fullscreen', + resize: 'vertical', + skin: 'lightgray', + theme: 'modern', + toolbar1: 'bold,italic,bullist,numlist,link', + }, + quicktags: { + buttons: 'strong,em,link,ul,ol,li,code', + }, +}); diff --git a/src/js/packages/api-fetch.js b/src/js/packages/api-fetch.js new file mode 100644 index 0000000..68e7de9 --- /dev/null +++ b/src/js/packages/api-fetch.js @@ -0,0 +1,21 @@ +import oApiFetch from 'gutenberg/packages/api-fetch/build-module'; + +// API settings +window.wpApiSettings = window.wpApiSettings || {}; +window.wpApiSettings.root = window.wpApiSettings.root || window.location.origin; +window.wpApiSettings.nonce = window.wpApiSettings.nonce || '123456789'; +window.wpApiSettings.versionString = window.wpApiSettings.versionString || 'wp/v2/'; + +// apiFetch +const apiFetch = window.wp.apiFetch || oApiFetch; +apiFetch.use = window.wp.apiFetch.use || oApiFetch.use; +apiFetch.createNonceMiddleware = window.wp.apiFetch.createNonceMiddleware || oApiFetch.createNonceMiddleware; +apiFetch.createPreloadingMiddleware = window.wp.apiFetch.createPreloadingMiddleware || oApiFetch.createPreloadingMiddleware; +apiFetch.createRootURLMiddleware = window.wp.apiFetch.createRootURLMiddleware || oApiFetch.createRootURLMiddleware; +apiFetch.fetchAllMiddleware = window.wp.apiFetch.fetchAllMiddleware || oApiFetch.fetchAllMiddleware; + +// Middleware +apiFetch.use(apiFetch.createNonceMiddleware(window.wpApiSettings.nonce)); +apiFetch.use(apiFetch.createRootURLMiddleware(window.wpApiSettings.root)); + +export default apiFetch; diff --git a/src/js/packages/data.js b/src/js/packages/data.js new file mode 100644 index 0000000..57b9aa9 --- /dev/null +++ b/src/js/packages/data.js @@ -0,0 +1,8 @@ +import * as data from '@wordpress/data'; + +const uid = window.userSettings ? window.userSettings.uid || 1 : 1; +const storageKey = `WP_DATA_USER_${uid}`; + +data +.use(data.plugins.persistence, { storageKey }) +.use(data.plugins.controls); diff --git a/src/js/packages/url.js b/src/js/packages/url.js new file mode 100644 index 0000000..721cb5f --- /dev/null +++ b/src/js/packages/url.js @@ -0,0 +1,6 @@ +import * as oUrl from 'gutenberg/packages/url/build-module'; + +export const url = { + ...oUrl, + ...window.wp.url, +}; diff --git a/src/js/wp-init.js b/src/js/wp-init.js deleted file mode 100644 index 4104a39..0000000 --- a/src/js/wp-init.js +++ /dev/null @@ -1,155 +0,0 @@ -/** - * External dependencies - */ -import React from 'react'; -import jQuery from 'jquery'; -import tinymce from 'tinymce'; -import memoize from 'memize'; - -import * as url from 'gutenberg/packages/url/build-module/index'; - -window.jQuery = window.jQuery || jQuery; -window.tinymce = window.tinymce || tinymce; -window.React = window.React || React; - -window.wp = window.wp || {}; - -// apiFetch -window.wp.apiFetch = window.wp.apiFetch || function (options) { - // do something here (this should be a promise) - return jQuery.ajax(options); -}; - -// URL -window.wp.url = window.wp.url || {}; -window.wp.url.addQueryArgs = window.wp.url.addQueryArgs || url.addQueryArgs; -window.wp.url.isURL = window.wp.url.isURL || url.isURL; -window.wp.url.prependHTTP = window.wp.url.prependHTTP || url.prependHTTP; - -window.wp.shortcode = window.wp.shortcode || {}; -window.wp.shortcode.regexp = window.wp.shortcode.regexp || memoize(function (tag) { - return new RegExp('\\[(\\[?)(' + tag + ')(?![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*(?:\\[(?!\\/\\2\\])[^\\[]*)*)(\\[\\/\\2\\]))?)(\\]?)', 'g'); -}); - -window.wp.editor = window.wp.editor || {}; -window.wp.editor.getDefaultSettings = window.wp.editor.getDefaultSettings || function () { - return { - tinymce: { - indent: true, - keep_styles: false, - menubar: false, - plugins: 'charmap,colorpicker,hr,lists,media,paste,tabfocus,textcolor,fullscreen', - resize: 'vertical', - skin: 'lightgray', - theme: 'modern', - toolbar1: 'bold,italic,bullist,numlist,link', - }, - quicktags: { - buttons: 'strong,em,link,ul,ol,li,code', - }, - }; -}; - -window.wp.editor.autop = window.wp.editor.autop || function () {}; -window.wp.editor.getContent = window.wp.editor.getContent || function (id) { - const editor = window.tinymce.get(id); - - if (editor && ! editor.isHidden()) { - editor.save(); - } - - return jQuery('#' + id).val(); -}; -window.wp.editor.initialize = window.wp.editor.initialize || function (id, settings = { tinymce: true }) { - const defaults = window.wp.editor.getDefaultSettings(); - const init = jQuery.extend({}, defaults.tinymce, settings.tinymce); - - init.selector = '#' + id; - - window.tinymce.init(init); - - if (! window.wpActiveEditor) { - window.wpActiveEditor = id; - } -}; -window.wp.editor.remove = window.wp.editor.remove || function (id) { - const mceInstance = window.tinymce.get(id); - - if (mceInstance) { - if (! mceInstance.isHidden()) { - mceInstance.save(); - } - - mceInstance.remove(); - } -}; -window.wp.editor.removep = window.wp.editor.removep || function () {}; - -window.wp.oldEditor = window.wp.editor; - -// wp api -window.wp.api = window.wp.api || {}; - -window.wp.api.models = window.wp.api.models || {}; -window.wp.api.collections = window.wp.api.collections || {}; -window.wp.api.views = window.wp.api.views || {}; - -// postTypes -window.wp.api.postTypeRestBaseMapping = window.wp.api.postTypeRestBaseMapping || { - attachment: 'media', - custom_css: 'custom_css', - customize_changeset: 'customize_changeset', - nav_menu_item: 'nav_menu_item', - oembed_cache: 'oembed_cache', - page: 'pages', - post: 'posts', - revision: 'revision', - user_request: 'user_request', - wp_block: 'blocks', -}; -window.wp.api.getPostTypeRoute = window.wp.api.getPostTypeRoute || function (postType) { - return window.wp.api.postTypeRestBaseMapping[ postType ]; -}; - -// taxonomies -window.wp.api.taxonomyRestBaseMapping = window.wp.api.taxonomyRestBaseMapping || { - category: 'categories', - link_category: 'link_category', - nav_menu : 'nav_menu', - post_format : 'post_format', - post_tag : 'tags', -}; -window.wp.api.getTaxonomyRoute = window.wp.api.getTaxonomyRoute || function (taxonomy) { - return window.wp.api.taxonomyRestBaseMapping[ taxonomy ]; -}; - -// User settings -window.userSettings = window.userSettings || {}; -window.userSettings.uid = window.userSettings.uid || 1; - -// Editor l10n settings -window.wpEditorL10n = window.wpEditorL10n || { - tinymce: { - baseUrl: 'node_modules/tinymce', - settings: { - external_plugins: [], - plugins: 'charmap,colorpicker,hr,lists,media,paste,tabfocus,textcolor,fullscreen', // ,wordpress,wpautoresize,wpeditimage,wpemoji,wpgallery,wplink,wpdialogs,wptextpattern,wpview', - toolbar1: 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,wp_more,spellchecker,kitchensink', - toolbar2: 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help', - toolbar3: '', - toolbar4: '', - }, - suffix: '.min', - }, -}; - -// API settings -window.wpApiSettings = window.wpApiSettings || {}; -window.wpApiSettings.root = window.wpApiSettings.root || window.location.origin; -window.wpApiSettings.nonce = window.wpApiSettings.nonce || '123456789'; -window.wpApiSettings.schema = window.wpApiSettings.schema || {}; -window.wpApiSettings.schema.routes = window.wpApiSettings.schema.routes || {}; -// window.wpApiSettings.schema.routes[ '/wp/v2/posts' ] = window.wpApiSettings.schema.routes[ '/wp/v2/posts' ] || { methods: [ 'GET' ] }; -// window.wpApiSettings.schema.routes[ '/wp/v2/posts/(?P[\\d]+)' ] = window.wpApiSettings.schema.routes[ '/wp/v2/posts/(?P[\\d]+)' ] || { methods: [ 'GET' ] }; -// window.wpApiSettings.schema.routes[ '/wp/v2/media' ] = window.wpApiSettings.schema.routes[ '/wp/v2/media' ] || { methods: [ 'GET' ] }; -// window.wpApiSettings.schema.routes[ '/wp/v2/media/(?P[\\d]+)' ] = window.wpApiSettings.schema.routes[ '/wp/v2/media/(?P[\\d]+)' ] || { methods: [ 'GET' ] }; diff --git a/src/scss/style.scss b/src/scss/style.scss index a1f8e91..1e1f915 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -1,6 +1,5 @@ // @import 'gbcolors'; @import 'media-library'; -@import 'block-drop-zone'; @media (min-width: 600px) { body .gutenberg__editor { From e282dea69855afa20de097ae8b4d1fd9d52ccadb Mon Sep 17 00:00:00 2001 From: Sofia Sousa Date: Wed, 31 Oct 2018 12:04:29 +0000 Subject: [PATCH 24/27] feat: Update overrides according gutenberg 4.2.0-rc --- .../packages/block-library/CHANGELOG.md | 4 +- .../block-library/build-module/cover/index.js | 731 +++++++++++------- .../build-module/gallery/edit.js | 17 +- .../build-module/gallery/gallery-image.js | 1 + .../build-module/gallery/index.js | 311 +++++++- .../block-library/build-module/image/edit.js | 30 +- .../block-library/build-module/image/index.js | 369 +++++++-- .../packages/blocks/CHANGELOG.md | 6 - .../blocks/build-module/api/parser.js | 31 +- .../packages/edit-post/CHANGELOG.md | 2 +- .../packages/editor/CHANGELOG.md | 4 +- .../build-module/components/inserter/menu.js | 123 ++- .../components/post-publish-panel/toggle.js | 54 +- .../components/post-saved-state/index.js | 126 ++- 14 files changed, 1358 insertions(+), 451 deletions(-) diff --git a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md index 5e35a75..feaa2a6 100644 --- a/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md +++ b/src/js/gutenberg-overrides/packages/block-library/CHANGELOG.md @@ -1,10 +1,10 @@ # block-library changelog -## 2.7.0 2018-10-25 +## 3.0.0 ### Changed -- 'cover-image' to 'cover' ([packages/block-library/build-module/cover](https://github.com/front/gutenberg-js/blob/v2.7.0/src/js/gutenberg-overrides/packages/block-library/build-module/cover)) +- 'cover-image' to 'cover' ([packages/block-library/build-module/cover](https://github.com/front/gutenberg-js/blob/v3.0.0/src/js/gutenberg-overrides/packages/block-library/build-module/cover)) ## 2.0.0 2018-08 diff --git a/src/js/gutenberg-overrides/packages/block-library/build-module/cover/index.js b/src/js/gutenberg-overrides/packages/block-library/build-module/cover/index.js index 5c1f01c..7a36ed6 100644 --- a/src/js/gutenberg-overrides/packages/block-library/build-module/cover/index.js +++ b/src/js/gutenberg-overrides/packages/block-library/build-module/cover/index.js @@ -7,9 +7,19 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { IconButton, PanelBody, RangeControl, ToggleControl, Toolbar, withNotices } from '@wordpress/components'; +import { + IconButton, + PanelBody, + RangeControl, + ToggleControl, + Toolbar, + withNotices, + SVG, + Path, +} from '@wordpress/components'; import { Fragment } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { createBlock } from '@wordpress/blocks'; import { compose } from '@wordpress/compose'; import { BlockControls, @@ -24,299 +34,500 @@ import { getColorClassName, } from '@wordpress/editor'; -import * as others from 'gutenberg/packages/block-library/build-module/cover/index?source=node_modules'; +const validAlignments = [ 'left', 'center', 'right', 'wide', 'full' ]; -function dimRatioToClass (ratio) { - return (ratio === 0 || ratio === 50) ? - null : - 'has-background-dim-' + (10 * Math.round(ratio / 10)); -} +const blockAttributes = { + title: { + type: 'string', + source: 'html', + selector: 'p', + }, + url: { + type: 'string', + }, + align: { + type: 'string', + }, + contentAlign: { + type: 'string', + default: 'center', + }, + id: { + type: 'number', + }, + hasParallax: { + type: 'boolean', + default: false, + }, + dimRatio: { + type: 'number', + default: 50, + }, + overlayColor: { + type: 'string', + }, + customOverlayColor: { + type: 'string', + }, + backgroundType: { + type: 'string', + default: 'image', + }, + // Gutenberg JS + data: { + type: 'object', + default: {}, + }, +}; -function backgroundImageStyles (url) { - return url ? - { backgroundImage: `url(${url})` } : - {}; -} +export const name = 'core/cover'; const ALLOWED_MEDIA_TYPES = [ 'image', 'video' ]; const IMAGE_BACKGROUND_TYPE = 'image'; const VIDEO_BACKGROUND_TYPE = 'video'; -// added data attributes (which is an object) -others.settings.attributes.data = { - type: 'object', - default: {}, -}; +export const settings = { + title: __('Cover'), -// overrired edit function to add data attributes -others.settings.edit = compose([ - withColors({ overlayColor: 'background-color' }), - withNotices, -])( - ({ attributes, setAttributes, isSelected, className, noticeOperations, noticeUI, overlayColor, setOverlayColor }) => { - const { - align, - backgroundType, - contentAlign, - dimRatio, - hasParallax, - id, - title, - url, - data, // GUTENBERG-JS - } = attributes; - const updateAlignment = nextAlign => setAttributes({ align: nextAlign }); - const onSelectMedia = media => { - if (! media || ! media.url) { - setAttributes({ url: undefined, id: undefined }); - return; - } - let mediaType; - // for media selections originated from a file upload. - if (media.media_type) { - if (media.media_type === IMAGE_BACKGROUND_TYPE) { - mediaType = IMAGE_BACKGROUND_TYPE; + description: __('Add an image or video with a text overlay — great for headers.'), + + icon: , + + category: 'common', + + attributes: blockAttributes, + + transforms: { + from: [ + { + type: 'block', + blocks: [ 'core/heading' ], + transform: ({ content }) => ( + createBlock('core/cover', { title: content }) + ), + }, + { + type: 'block', + blocks: [ 'core/image' ], + transform: ({ caption, url, align, id }) => ( + createBlock('core/cover', { + title: caption, + url, + align, + id, + }) + ), + }, + { + type: 'block', + blocks: [ 'core/video' ], + transform: ({ caption, src, align, id }) => ( + createBlock('core/cover', { + title: caption, + url: src, + align, + id, + backgroundType: VIDEO_BACKGROUND_TYPE, + }) + ), + }, + ], + to: [ + { + type: 'block', + blocks: [ 'core/heading' ], + transform: ({ title }) => ( + createBlock('core/heading', { content: title }) + ), + }, + { + type: 'block', + blocks: [ 'core/image' ], + isMatch: ({ backgroundType, url }) => { + return ! url || backgroundType === IMAGE_BACKGROUND_TYPE; + }, + transform: ({ title, url, align, id }) => ( + createBlock('core/image', { + caption: title, + url, + align, + id, + }) + ), + }, + { + type: 'block', + blocks: [ 'core/video' ], + isMatch: ({ backgroundType, url }) => { + return ! url || backgroundType === VIDEO_BACKGROUND_TYPE; + }, + transform: ({ title, url, align, id }) => ( + createBlock('core/video', { + caption: title, + src: url, + id, + align, + }) + ), + }, + ], + }, + + getEditWrapperProps (attributes) { + const { align } = attributes; + if (-1 !== validAlignments.indexOf(align)) { + return { 'data-align': align }; + } + }, + + edit: compose([ + withColors({ overlayColor: 'background-color' }), + withNotices, + ])( + ({ attributes, setAttributes, isSelected, className, noticeOperations, noticeUI, overlayColor, setOverlayColor }) => { + const { + align, + backgroundType, + contentAlign, + dimRatio, + hasParallax, + id, + title, + url, + // Gutenberg JS + data, + } = attributes; + const updateAlignment = nextAlign => setAttributes({ align: nextAlign }); + const onSelectMedia = media => { + if (! media || ! media.url) { + setAttributes({ url: undefined, id: undefined }); + return; } - else { - // only images and videos are accepted so if the media_type is not an image we can assume it is a video. - // Videos contain the media type of 'file' in the object returned from the rest api. - mediaType = VIDEO_BACKGROUND_TYPE; + let mediaType; + // for media selections originated from a file upload. + if (media.media_type) { + if (media.media_type === IMAGE_BACKGROUND_TYPE) { + mediaType = IMAGE_BACKGROUND_TYPE; + } + else { + // only images and videos are accepted so if the media_type is not an image we can assume it is a video. + // Videos contain the media type of 'file' in the object returned from the rest api. + mediaType = VIDEO_BACKGROUND_TYPE; + } } - } - else { // for media selections originated from existing files in the media library. - if ( - media.type !== IMAGE_BACKGROUND_TYPE && - media.type !== VIDEO_BACKGROUND_TYPE - ) { - return; + else { // for media selections originated from existing files in the media library. + if ( + media.type !== IMAGE_BACKGROUND_TYPE && + media.type !== VIDEO_BACKGROUND_TYPE + ) { + return; + } + mediaType = media.type; } - mediaType = media.type; - } - // GUTENBERG-JS - const toUpdate = { - url: media.url, - id: media.id, - backgroundType: mediaType, + // GUTENBERG JS + // setAttributes({ + const toUpdate = { + url: media.url, + id: media.id, + backgroundType: mediaType, + }; + // }); + + if (media.data) { + toUpdate.data = Object.keys(media.data) + .reduce((result, key) => { + result[`data-${key.replace('_', '-')}`] = media.data[key]; + + return result; + }, {}); + } + + setAttributes(toUpdate); }; + const toggleParallax = () => setAttributes({ hasParallax: ! hasParallax }); + const setDimRatio = ratio => setAttributes({ dimRatio: ratio }); + const setTitle = newTitle => setAttributes({ title: newTitle }); - if (media.data) { - toUpdate.data = Object.keys(media.data) - .reduce((result, key) => { - result[`data-${key.replace('_', '-')}`] = media.data[key]; + const style = { + ...( + backgroundType === IMAGE_BACKGROUND_TYPE ? + backgroundImageStyles(url) : + {} + ), + backgroundColor: overlayColor.color, + }; - return result; - }, {}); + const classes = classnames( + className, + contentAlign !== 'center' && `has-${contentAlign}-content`, + dimRatioToClass(dimRatio), + { + 'has-background-dim': dimRatio !== 0, + 'has-parallax': hasParallax, + } + ); + + const controls = ( + + + + { !! url && ( + + { + setAttributes({ contentAlign: nextAlign }); + } } + /> + + ( + + ) } + /> + + + ) } + + { !! url && ( + + + { IMAGE_BACKGROUND_TYPE === backgroundType && ( + + ) } + + + + + + ) } + + ); + + if (! url) { + const hasTitle = ! RichText.isEmpty(title); + const icon = hasTitle ? undefined : 'format-image'; + const label = hasTitle ? ( + + ) : __('Cover'); + + return ( + + { controls } + + + ); } - setAttributes(toUpdate); - }; - const toggleParallax = () => setAttributes({ hasParallax: ! hasParallax }); - const setDimRatio = ratio => setAttributes({ dimRatio: ratio }); - const setTitle = newTitle => setAttributes({ title: newTitle }); - - const style = { - ...( - backgroundType === IMAGE_BACKGROUND_TYPE ? - backgroundImageStyles(url) : - {} - ), - backgroundColor: overlayColor.color, - }; + return ( + + { controls } +
+ { VIDEO_BACKGROUND_TYPE === backgroundType && ( +
+
+ ); + } + ), + + save ({ attributes, className }) { + const { + align, + backgroundType, + contentAlign, + customOverlayColor, + dimRatio, + hasParallax, + overlayColor, + title, + url, + // GUTENBERG JS + data, + } = attributes; + const overlayColorClass = getColorClassName('background-color', overlayColor); + const style = backgroundType === IMAGE_BACKGROUND_TYPE ? + backgroundImageStyles(url) : + {}; + if (! overlayColorClass) { + style.backgroundColor = customOverlayColor; + } const classes = classnames( className, - contentAlign !== 'center' && `has-${contentAlign}-content`, dimRatioToClass(dimRatio), + overlayColorClass, { 'has-background-dim': dimRatio !== 0, 'has-parallax': hasParallax, - } + [ `has-${contentAlign}-content` ]: contentAlign !== 'center', + }, + align ? `align${align}` : null, ); - const controls = ( - - - - { !! url && ( - - { - setAttributes({ contentAlign: nextAlign }); - } } - /> - - ( - - ) } - /> - - - ) } - - { !! url && ( - - - { IMAGE_BACKGROUND_TYPE === backgroundType && ( - - ) } - - - - - + return ( +
+ { VIDEO_BACKGROUND_TYPE === backgroundType && url && (
); + }, - if (! url) { - const hasTitle = ! RichText.isEmpty(title); - const icon = hasTitle ? undefined : 'format-image'; - const label = hasTitle ? ( - - ) : __('Cover'); + deprecated: [ { + attributes: { + ...blockAttributes, + }, - return ( - - { controls } - - + supports: { + className: false, + }, + + save ({ attributes }) { + const { url, title, hasParallax, dimRatio, align, contentAlign, overlayColor, customOverlayColor } = attributes; + const overlayColorClass = getColorClassName('background-color', overlayColor); + const style = backgroundImageStyles(url); + if (! overlayColorClass) { + style.backgroundColor = customOverlayColor; + } + + const classes = classnames( + 'wp-block-cover-image', + dimRatioToClass(dimRatio), + overlayColorClass, + { + 'has-background-dim': dimRatio !== 0, + 'has-parallax': hasParallax, + [ `has-${contentAlign}-content` ]: contentAlign !== 'center', + }, + align ? `align${align}` : null, ); - } - return ( - - { controls } -
- { VIDEO_BACKGROUND_TYPE === backgroundType && ( -