Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TinyMCE per block: Enhancing the embed block #203

Merged
merged 1 commit into from
Mar 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions tinymce-per-block/build/app.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions tinymce-per-block/src/assets/stylesheets/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
font-weight: 300;
font-size: 14px;
color: $gray-dark-300;
text-align: center;
}
}

Expand Down
69 changes: 66 additions & 3 deletions tinymce-per-block/src/blocks/embed-block/_style.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,41 @@
.embed-block__form textarea, .embed-block__form .textarea-mirror {
.embed-block__form {
margin: 50px auto;
width: 50%;
textarea, .textarea-mirror {
width: 100%;
border: 1px solid $gray-light;
border-radius: 4px;
padding: 6px 12px;
font: inherit;
font-weight: 300;
font-size: 14px;
color: $gray-dark-300;
resize: none;

&:focus {
outline: 0;
}
}

.embed-block__title {
color: #87919d;
text-align: center;
vertical-align: middle;
font-weight: bold;
margin-bottom: 10px;

.dashicon {
width: 24px;
height: 24px;
vertical-align: middle;
margin-right: 5px;
fill: #87919d;
}
}
}

.embed-block__caption textarea,
.embed-block__caption .textarea-mirror {
margin-top: 10px;
width: 100%;
border: none;
Expand All @@ -8,12 +45,38 @@
font-size: 14px;
color: $gray-dark-300;
resize: none;
text-align: center;

&:focus {
outline: 0;
}
}

.embed-block__content iframe {
width: 100%;
.embed-block {
&.align-full-width {
margin-left: calc(50% - 50vw);
width: 100vw;
max-width: none;
padding-left: 0;
padding-right: 0;

.embed-block__content {
width: 100%;
}
}

&.align-left {
float: left;
z-index: 1;
}

&.align-right {
float: right;
z-index: 1;
}

&.align-center {
text-align: center;
max-width: 100%;
}
}
79 changes: 61 additions & 18 deletions tinymce-per-block/src/blocks/embed-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,93 @@
* External dependencies
*/
import { createElement, Component } from 'wp-elements';
import { CloudOutline } from 'dashicons';
import classNames from 'classnames';

/**
* Internal Dependencies
*/
import { EnhancedInputComponent } from 'wp-blocks';
import BlockArrangement from 'controls/block-arrangement';
import { getEmbedHtmlFromUrl } from '../../utils/embed';
import FigureAlignmentToolbar from 'controls/figure-alignment-toolbar';

export default class EmbedBlockForm extends Component {
merge = () => {
this.props.remove();
};

bindInput = ( ref ) => {
this.input = ref;
setAlignment = ( id ) => {
this.props.change( { align: id } );
};

render() {
const { block, isSelected, change, moveCursorUp, moveCursorDown,
remove, focusConfig, focus, moveBlockUp, moveBlockDown } = this.props;
remove, focusConfig, focus, moveBlockUp, moveBlockDown, appendBlock } = this.props;

const removePrevious = () => {
if ( ! block.url ) {
remove();
}
};
const splitValue = ( left, right ) => {
change( { caption: left } );
appendBlock( {
blockType: 'text',
content: right
} );
};

const html = getEmbedHtmlFromUrl( block.url );

return (
<div>
<div className={ classNames( 'embed-block', block.align ) }>
{ isSelected && <BlockArrangement block={ block }
moveBlockUp={ moveBlockUp } moveBlockDown={ moveBlockDown } /> }
<div className="embed-block__form">
<div className="embed-block__content" dangerouslySetInnerHTML={ { __html: html } } />
<EnhancedInputComponent
ref={ this.bindInput }
moveCursorUp={ moveCursorUp }
removePrevious={ removePrevious }
moveCursorDown={ moveCursorDown }
value={ block.url }
onChange={ ( value ) => change( { url: value } ) }
focusConfig={ focusConfig }
onFocusChange={ ( config ) => focus( config ) }
placeholder="Enter an embed URL"
/>
</div>
{ isSelected &&
<div className="block-list__block-controls">
<div className="block-list__block-controls-group">
<FigureAlignmentToolbar value={ block.align } onChange={ this.setAlignment } />
</div>
</div>
}
{ ! block.url &&
<div className="embed-block__form">
<div className="embed-block__title">
<CloudOutline /> Embed URL
</div>
<EnhancedInputComponent
ref={ this.bindInput }
moveCursorUp={ moveCursorUp }
removePrevious={ removePrevious }
moveCursorDown={ moveCursorDown }
value={ block.url }
onChange={ ( value ) => change( { url: value } ) }
focusConfig={ focusConfig }
onFocusChange={ ( config ) => focus( config ) }
placeholder="Paste URL to embed here..."
/>
</div>
}
{ block.url &&
<div className="embed-block__content">
<div dangerouslySetInnerHTML={ { __html: html } } />
<div className="embed-block__caption">
<EnhancedInputComponent
ref={ this.bindCaption }
moveCursorUp={ moveCursorUp }
removePrevious={ removePrevious }
moveCursorDown={ moveCursorDown }
splitValue={ splitValue }
value={ block.caption }
onChange={ ( value ) => change( { caption: value } ) }
placeholder="Write caption"
focusConfig={ focusConfig }
onFocusChange={ focus }
/>
</div>
</div>
}
</div>
);
}
Expand Down
28 changes: 24 additions & 4 deletions tinymce-per-block/src/blocks/embed-block/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,49 @@ import { VideoAlt3Icon } from 'dashicons';
* Internal dependencies
*/
import form from './form';
import { getEmbedHtmlFromUrl } from '../../utils/embed';
import { getEmbedHtmlFromUrl } from 'utils/embed';
import { getFigureAlignmentStyles } from 'utils/figure-alignment';

registerBlock( 'embed', {
title: 'Embed',
form: form,
icon: VideoAlt3Icon,
parse: ( rawBlock ) => {
const div = document.createElement( 'div' );
div.innerHTML = rawBlock.rawContent;
const captionNode = div.firstChild.nodeName === 'FIGURE'
? div.firstChild.querySelector( 'figure > figcaption' )
: null;
const caption = captionNode ? captionNode.innerHTML : '';

return {
blockType: 'embed',
url: rawBlock.attrs.url,
align: rawBlock.attrs.align,
caption
};
},
serialize: ( block ) => {
const styles = getFigureAlignmentStyles( block.align );
const rawContent = [
`<figure${ styles.figure }>`,
`<div${ styles.content }>${ getEmbedHtmlFromUrl( block.url ) }</div>`,
`<figcaption>${ block.caption }</figcaption>`,
'</figure>'
].join( '' );

return {
blockType: 'embed',
attrs: { url: block.url },
rawContent: getEmbedHtmlFromUrl( block.url )
attrs: { url: block.url, align: block.align },
rawContent
};
},
create: () => {
return {
blockType: 'embed',
url: ''
url: '',
align: 'no-align',
caption: ''
};
}
} );
7 changes: 5 additions & 2 deletions tinymce-per-block/src/blocks/html-block/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,23 @@ registerBlock( 'html', {
blockType: 'html',
align: rawBlock.attrs.align || 'no-align',
content: rawBlock.rawContent,
caption: rawBlock.caption
};
},
serialize: ( block ) => {
return {
blockType: 'html',
attrs: { align: block.align },
rawContent: block.content
rawContent: block.content,
caption: block.caption
};
},
create: () => {
return {
blockType: 'html',
content: '',
align: 'no-align'
align: 'no-align',
caption: ''
};
}
} );
7 changes: 6 additions & 1 deletion tinymce-per-block/src/blocks/image-block/_style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@
z-index: 1;
}

&.align-center {
text-align: center;
max-width: 100%;
}

.image-block__display {
display: block;
display: inline-block;
max-width: 100%;
}

Expand All @@ -42,6 +46,7 @@
font-size: 14px;
color: $gray-dark-300;
resize: none;
text-align: center;

&:focus {
outline: 0;
Expand Down
37 changes: 5 additions & 32 deletions tinymce-per-block/src/blocks/image-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,19 @@
* External dependencies
*/
import { createElement, Component } from 'wp-elements';
import {
ImageNoAlignIcon,
ImageAlignRightIcon,
ImageAlignLeftIcon,
ImageFullWidthIcon
} from 'dashicons';
import classNames from 'classnames';

import { EnhancedInputComponent } from 'wp-blocks';
import BlockArrangement from 'controls/block-arrangement';
import FigureAlignmentToolbar from 'controls/figure-alignment-toolbar';

export default class ImageBlockForm extends Component {

merge() {
this.props.remove();
}

bindCaption = ( ref ) => {
this.caption = ref;
}

setImageAlignment = ( id ) => () => {
setAlignment = ( id ) => {
this.props.change( { align: id } );
};

Expand All @@ -42,32 +33,15 @@ export default class ImageBlockForm extends Component {
content: right
} );
};
const imageAlignments = [
{ id: 'no-align', icon: ImageNoAlignIcon },
{ id: 'align-left', icon: ImageAlignLeftIcon },
{ id: 'align-right', icon: ImageAlignRightIcon },
{ id: 'align-full-width', icon: ImageFullWidthIcon },
];
const alignValue = block.align || 'no-align';

return (
<div className={ classNames( 'image-block__form', alignValue ) }>
<div className={ classNames( 'image-block__form', block.align ) }>
{ isSelected && <BlockArrangement block={ block }
moveBlockUp={ moveBlockUp } moveBlockDown={ moveBlockDown } /> }
{ isSelected &&
<div className="block-list__block-controls">
<div className="block-list__block-controls-group">
{ imageAlignments.map( ( { id, icon: Icon } ) =>
<button
key={ id }
onClick={ this.setImageAlignment( id ) }
className={ classNames( 'block-list__block-control', {
'is-selected': alignValue === id
} ) }
>
<Icon />
</button>
) }
<FigureAlignmentToolbar value={ block.align } onChange={ this.setAlignment } />
</div>
</div>
}
Expand All @@ -80,14 +54,13 @@ export default class ImageBlockForm extends Component {
/>
<div className="image-block__caption">
<EnhancedInputComponent
ref={ this.bindCaption }
moveCursorUp={ moveCursorUp }
removePrevious={ removePrevious }
moveCursorDown={ moveCursorDown }
splitValue={ splitValue }
value={ block.caption }
onChange={ ( value ) => change( { caption: value } ) }
placeholder="Enter a caption"
placeholder="Write caption"
focusConfig={ focusConfig }
onFocusChange={ focus }
/>
Expand Down
Loading