diff --git a/blocks/editable/index.js b/blocks/editable/index.js index 9c0ac6afc12d4..a02964b7a7fc4 100644 --- a/blocks/editable/index.js +++ b/blocks/editable/index.js @@ -2,7 +2,7 @@ * External dependencies */ import classnames from 'classnames'; -import { last, isEqual, capitalize, omitBy, forEach, merge } from 'lodash'; +import { last, isEqual, capitalize, omitBy, forEach, merge, identity } from 'lodash'; import { nodeListToReact } from 'dom-react'; import { Fill } from 'react-slot-fill'; import 'element-closest'; @@ -67,6 +67,7 @@ export default class Editable extends wp.element.Component { super( ...arguments ); this.onInit = this.onInit.bind( this ); + this.getSettings = this.getSettings.bind( this ); this.onSetup = this.onSetup.bind( this ); this.onChange = this.onChange.bind( this ); this.onNewBlock = this.onNewBlock.bind( this ); @@ -84,6 +85,13 @@ export default class Editable extends wp.element.Component { }; } + getSettings( settings ) { + return ( this.props.getSettings || identity )( { + ...settings, + forced_root_block: this.props.inline ? false : 'p', + } ); + } + onSetup( editor ) { this.editor = editor; editor.on( 'init', this.onInit ); @@ -93,6 +101,10 @@ export default class Editable extends wp.element.Component { editor.on( 'nodechange', this.onNodeChange ); editor.on( 'keydown', this.onKeyDown ); editor.on( 'selectionChange', this.onSelectionChange ); + + if ( this.props.onSetup ) { + this.props.onSetup( editor ); + } } onInit() { @@ -394,7 +406,6 @@ export default class Editable extends wp.element.Component { className, showAlignments = false, inlineToolbar = false, - inline, formattingControls, placeholder, } = this.props; @@ -438,12 +449,10 @@ export default class Editable extends wp.element.Component { diff --git a/blocks/editable/tinymce.js b/blocks/editable/tinymce.js index 72f8fad07390f..e12b769474319 100644 --- a/blocks/editable/tinymce.js +++ b/blocks/editable/tinymce.js @@ -34,24 +34,27 @@ export default class TinyMCE extends wp.element.Component { } initialize() { - const { settings, focus } = this.props; + const { focus } = this.props; - tinymce.init( { - target: this.editorNode, + const settings = this.props.getSettings( { theme: false, inline: true, toolbar: false, browser_spellcheck: true, entity_encoding: 'raw', convert_urls: false, - setup: ( editor ) => { - this.editor = editor; - this.props.onSetup( editor ); - }, formats: { strikethrough: { inline: 'del' }, }, + } ); + + tinymce.init( { ...settings, + target: this.editorNode, + setup: ( editor ) => { + this.editor = editor; + this.props.onSetup( editor ); + }, } ); if ( focus ) { diff --git a/blocks/library/list/index.js b/blocks/library/list/index.js index b3ffbf97a3e6f..46b0acf18d812 100644 --- a/blocks/library/list/index.js +++ b/blocks/library/list/index.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { switchChildrenNodeName } from 'element'; +import { find } from 'lodash'; /** * Internal dependencies @@ -12,6 +13,40 @@ import Editable from '../../editable'; const { children, prop } = hpq; +function execCommand( command ) { + return ( { editor } ) => { + if ( editor ) { + editor.execCommand( command ); + } + }; +} + +function listIsActive( listType ) { + return ( { nodeName = 'OL', internalListType } ) => { + return listType === ( internalListType ? internalListType : nodeName ); + }; +} + +function listSetType( listType, editorCommand ) { + return ( { internalListType, editor }, setAttributes ) => { + if ( internalListType ) { + // only change list types, don't toggle off internal lists + if ( internalListType !== listType ) { + if ( editor ) { + editor.execCommand( editorCommand ); + } + } + } else { + setAttributes( { nodeName: listType } ); + } + }; +} + +function findInternalListType( { parents } ) { + const list = find( parents, ( node ) => node.nodeName === 'UL' || node.nodeName === 'OL' ); + return list ? list.nodeName : null; +} + registerBlock( 'core/list', { title: wp.i18n.__( 'List' ), icon: 'editor-ul', @@ -26,18 +61,24 @@ registerBlock( 'core/list', { { icon: 'editor-ul', title: wp.i18n.__( 'Convert to unordered' ), - isActive: ( { nodeName = 'OL' } ) => nodeName === 'UL', - onClick( attributes, setAttributes ) { - setAttributes( { nodeName: 'UL' } ); - }, + isActive: listIsActive( 'UL' ), + onClick: listSetType( 'UL', 'InsertUnorderedList' ), }, { icon: 'editor-ol', title: wp.i18n.__( 'Convert to ordered' ), - isActive: ( { nodeName = 'OL' } ) => nodeName === 'OL', - onClick( attributes, setAttributes ) { - setAttributes( { nodeName: 'OL' } ); - }, + isActive: listIsActive( 'OL' ), + onClick: listSetType( 'OL', 'InsertOrderedList' ), + }, + { + icon: 'editor-outdent', + title: wp.i18n.__( 'Outdent list item' ), + onClick: execCommand( 'Outdent' ), + }, + { + icon: 'editor-indent', + title: wp.i18n.__( 'Indent list item' ), + onClick: execCommand( 'Indent' ), }, ], @@ -72,6 +113,17 @@ registerBlock( 'core/list', { return ( ( { + ...settings, + plugins: ( settings.plugins || [] ).concat( 'lists' ), + lists_indent_on_tab: false, + } ) } + onSetup={ ( editor ) => { + editor.on( 'nodeChange', ( nodeInfo ) => { + setAttributes( { internalListType: findInternalListType( nodeInfo ) } ); + } ); + setAttributes( { editor } ); + } } onChange={ ( nextValues ) => { setAttributes( { values: nextValues } ); } } diff --git a/blocks/library/list/style.scss b/blocks/library/list/style.scss index 4626951e7d302..4448ee1c55d8f 100644 --- a/blocks/library/list/style.scss +++ b/blocks/library/list/style.scss @@ -1,3 +1,6 @@ -.blocks-list .blocks-editable__tinymce { +.blocks-list .blocks-editable__tinymce, +.blocks-list .blocks-editable__tinymce ul, +.blocks-list .blocks-editable__tinymce ol { padding-left: 2.5em; + margin-left: 0; } diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index f612e32760921..31b9f020327bb 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -205,7 +205,7 @@ class VisualEditorBlock extends wp.element.Component { controls={ settings.controls.map( ( control ) => ( { ...control, onClick: () => control.onClick( block.attributes, this.setAttributes ), - isActive: control.isActive( block.attributes ), + isActive: control.isActive ? control.isActive( block.attributes ) : false, } ) ) } /> ) }