Skip to content

Commit

Permalink
Add Inline Images and Inline Blocks API (#6959)
Browse files Browse the repository at this point in the history
* Add Inline Images and Inline Blocks API

* Fix test

* e2e: leave time for upload

* e2e: fix multi selection test

* e2e: wait for media modal

* Address some feedback

* Try search + click for block insert test

* Rebase and address feedback

* Try with data layer

* Move registering tokens to store init

* Rebase and test adjustments

* Run tests in band

* Generate a unique name for the upload image on each test run

* Remove the deletion of previous images
  • Loading branch information
ellatrix authored Jun 28, 2018
1 parent eecb1ea commit 3fd1328
Show file tree
Hide file tree
Showing 27 changed files with 476 additions and 21 deletions.
2 changes: 2 additions & 0 deletions blocks/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export {
} from './registration';
export {
isUnmodifiedDefaultBlock,
normalizeIconObject,
isValidIcon,
} from './utils';
export {
doBlocksMatchTemplate,
Expand Down
8 changes: 2 additions & 6 deletions components/slot-fill/slot.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,9 @@ class Slot extends Component {

const fills = map( getFills( name ), ( fill ) => {
const fillKey = fill.occurrence;
const fillChildren = isFunction( fill.props.children ) ? fill.props.children( fillProps ) : fill.props.children;

// If a function is passed as a child, render it with the fillProps.
if ( isFunction( fill.props.children ) ) {
return cloneElement( fill.props.children( fillProps ), { key: fillKey } );
}

return Children.map( fill.props.children, ( child, childIndex ) => {
return Children.map( fillChildren, ( child, childIndex ) => {
if ( ! child || isString( child ) ) {
return child;
}
Expand Down
4 changes: 4 additions & 0 deletions core-blocks/gallery/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
width: 100%;
max-height: 100%;
overflow: auto;

img {
display: inline;
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions core-blocks/image/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
&.is-transient img {
@include loading_fade;
}

figcaption img {
display: inline;
}
}

.wp-block-image__resize-handler-top-right,
Expand Down
10 changes: 10 additions & 0 deletions edit-post/hooks/components/media-upload/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class MediaUpload extends Component {
this.onOpen = this.onOpen.bind( this );
this.onSelect = this.onSelect.bind( this );
this.onUpdate = this.onUpdate.bind( this );
this.onClose = this.onClose.bind( this );
this.processMediaCaption = this.processMediaCaption.bind( this );

if ( gallery ) {
Expand Down Expand Up @@ -122,6 +123,7 @@ class MediaUpload extends Component {
this.frame.on( 'select', this.onSelect );
this.frame.on( 'update', this.onUpdate );
this.frame.on( 'open', this.onOpen );
this.frame.on( 'close', this.onClose );
}

componentWillUnmount() {
Expand Down Expand Up @@ -169,6 +171,14 @@ class MediaUpload extends Component {
getAttachmentsCollection( castArray( this.props.value ) ).more();
}

onClose() {
const { onClose } = this.props;

if ( onClose ) {
onClose();
}
}

openModal() {
this.frame.open();
}
Expand Down
5 changes: 4 additions & 1 deletion editor/components/block-types-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ class BlockTypesList extends Component {
}
)
}
onClick={ () => onSelect( item ) }
onClick={ () => {
onSelect( item );
onHover( null );
} }
disabled={ item.isDisabled }
onMouseEnter={ () => onHover( item ) }
onMouseLeave={ () => onHover( null ) }
Expand Down
10 changes: 2 additions & 8 deletions editor/components/inserter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { withSelect, withDispatch } from '@wordpress/data';
*/
import InserterMenu from './menu';

export { default as InserterResultsPortal } from './results-portal';

class Inserter extends Component {
constructor() {
super( ...arguments );
Expand All @@ -22,12 +24,6 @@ class Inserter extends Component {
onToggle( isOpen ) {
const { onToggle } = this.props;

if ( isOpen ) {
this.props.showInsertionPoint();
} else {
this.props.hideInsertionPoint();
}

// Surface toggle callback to parent component
if ( onToggle ) {
onToggle( isOpen );
Expand Down Expand Up @@ -101,8 +97,6 @@ export default compose( [
};
} ),
withDispatch( ( dispatch, ownProps ) => ( {
showInsertionPoint: dispatch( 'core/editor' ).showInsertionPoint,
hideInsertionPoint: dispatch( 'core/editor' ).hideInsertionPoint,
onInsertBlock: ( item ) => {
const { insertionPoint, selectedBlock } = ownProps;
const { index, rootUID, layout } = insertionPoint;
Expand Down
11 changes: 11 additions & 0 deletions editor/components/inserter/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import './style.scss';
import BlockPreview from '../block-preview';
import BlockTypesList from '../block-types-list';
import ChildBlocks from './child-blocks';
import InserterResultsPortal from './results-portal';

const MAX_SUGGESTED_ITEMS = 9;

Expand Down Expand Up @@ -95,6 +96,12 @@ export class InserterMenu extends Component {
this.setState( {
hoveredItem: item,
} );

if ( item ) {
this.props.showInsertionPoint();
} else {
this.props.hideInsertionPoint();
}
}

bindPanel( name ) {
Expand Down Expand Up @@ -201,6 +208,8 @@ export class InserterMenu extends Component {
/>

<div className="editor-inserter__results" ref={ this.inserterResults }>
<InserterResultsPortal.Slot fillProps={ { filterValue } } />

<ChildBlocks
rootUID={ rootUID }
items={ childItems }
Expand Down Expand Up @@ -275,6 +284,8 @@ export default compose(
} ),
withDispatch( ( dispatch ) => ( {
fetchSharedBlocks: dispatch( 'core/editor' ).fetchSharedBlocks,
showInsertionPoint: dispatch( 'core/editor' ).showInsertionPoint,
hideInsertionPoint: dispatch( 'core/editor' ).hideInsertionPoint,
} ) ),
withSpokenMessages,
withInstanceId,
Expand Down
38 changes: 38 additions & 0 deletions editor/components/inserter/results-portal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* WordPress dependencies
*/
import { createSlotFill, PanelBody } from '@wordpress/components';

/**
* Internal dependencies
*/
import BlockTypesList from '../block-types-list';
import { searchItems } from './menu';

const { Fill, Slot } = createSlotFill( 'InserterResultsPortal' );

const InserterResultsPortal = ( { items, title, onSelect, onHover } ) => {
return (
<Fill>
{ ( { filterValue } ) => {
const filteredItems = searchItems( items, filterValue );

if ( ! filteredItems.length ) {
return null;
}

return (
<PanelBody
title={ title }
>
<BlockTypesList items={ filteredItems } onSelect={ onSelect } onHover={ onHover } />
</PanelBody>
);
} }
</Fill>
);
};

InserterResultsPortal.Slot = Slot;

export default InserterResultsPortal;
11 changes: 11 additions & 0 deletions editor/components/rich-text/core-tokens/image/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.mce-content-body div.mce-resizehandle {
border-radius: 50%;
border: 2px solid $white;
width: 15px !important;
height: 15px !important;
position: absolute;
background: theme( primary );
padding: 0 3px 3px 0;
box-sizing: border-box;
cursor: se-resize;
}
48 changes: 48 additions & 0 deletions editor/components/rich-text/core-tokens/image/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import './editor.scss';
import MediaUpload from '../../../media-upload';

export const name = 'core/image';

export const settings = {
id: 'image',

title: __( 'Inline Image' ),

type: 'image',

icon: 'format-image',

edit( { onSave } ) {
return (
<MediaUpload
type="image"
onSelect={ ( media ) => onSave( media ) }
onClose={ () => onSave( null ) }
render={ ( { open } ) => {
open();
return null;
} }
/>
);
},

save( { id, url, alt, width } ) {
return (
<img
className={ `wp-image-${ id }` }
// set width in style attribute to prevent Block CSS from overriding it
style={ { width: `${ Math.min( width, 150 ) }px` } }
src={ url }
alt={ alt }
/>
);
},
};
6 changes: 6 additions & 0 deletions editor/components/rich-text/core-tokens/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Internal dependencies
*/
import * as image from './image';

export { image };
7 changes: 7 additions & 0 deletions editor/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { pickAriaProps } from './aria';
import patterns from './patterns';
import { withBlockEditContext } from '../block-edit/context';
import { domToFormat, valueToString } from './format';
import TokenUI from './tokens/ui';

/**
* Returns true if the node is the inline node boundary. This is used in node
Expand Down Expand Up @@ -885,6 +886,12 @@ export class RichText extends Component {
{ formatToolbar }
</div>
) }
{ isSelected &&
<TokenUI
editor={ this.editor }
containerRef={ this.containerRef }
/>
}
<Autocomplete onReplace={ this.props.onReplace } completers={ autocompleters }>
{ ( { isExpanded, listBoxId, activeId } ) => (
<Fragment>
Expand Down
10 changes: 10 additions & 0 deletions editor/components/rich-text/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@
}
}

img {
&[data-mce-selected] {
outline: none;
}

&::selection {
background: none !important;
}
}

&[data-is-placeholder-visible="true"] {
position: absolute;
top: 0;
Expand Down
Loading

0 comments on commit 3fd1328

Please sign in to comment.