Skip to content

Commit

Permalink
Add logic to change list type
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Dec 8, 2018
1 parent 629d0c9 commit 794c90e
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 43 deletions.
2 changes: 0 additions & 2 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ function register_tinymce_scripts() {
gutenberg_override_script( 'wp-tinymce-root', includes_url( 'js/tinymce/' ) . "tinymce{$mce_suffix}.js", array(), $tinymce_version );
gutenberg_override_script( 'wp-tinymce', includes_url( 'js/tinymce/' ) . "plugins/compat3x/plugin{$suffix}.js", array( 'wp-tinymce-root' ), $tinymce_version );
}

gutenberg_override_script( 'wp-tinymce-lists', includes_url( 'js/tinymce/' ) . "plugins/lists/plugin{$suffix}.js", array( 'wp-tinymce' ), $tinymce_version );
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/packages-dependencies.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
'wp-editor' => array(
'jquery',
'lodash',
'wp-tinymce-lists',
'wp-tinymce',
'wp-a11y',
'wp-api-fetch',
'wp-blob',
Expand Down
15 changes: 1 addition & 14 deletions packages/editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ export class RichText extends Component {
this.onSplit = this.props.unstableOnSplit;
}

this.onSetup = this.onSetup.bind( this );
this.onFocus = this.onFocus.bind( this );
this.onBlur = this.onBlur.bind( this );
this.onChange = this.onChange.bind( this );
Expand Down Expand Up @@ -133,15 +132,6 @@ export class RichText extends Component {
this.editableRef = node;
}

/**
* Sets a reference to the TinyMCE editor instance.
*
* @param {Editor} editor The editor instance as passed by TinyMCE.
*/
onSetup( editor ) {
this.editor = editor;
}

setFocusedElement() {
if ( this.props.setFocusedElement ) {
this.props.setFocusedElement( this.props.instanceId );
Expand Down Expand Up @@ -831,12 +821,10 @@ export class RichText extends Component {
<div className={ classes }
onFocus={ this.setFocusedElement }
>
{ isSelected && this.editor && this.multilineTag === 'li' && (
{ isSelected && this.multilineTag === 'li' && (
<ListEdit
editor={ this.editor }
onTagNameChange={ onTagNameChange }
tagName={ Tagname }
onSyncDOM={ () => this.onChange( this.createRecord() ) }
value={ record }
onChange={ this.onChange }
/>
Expand All @@ -861,7 +849,6 @@ export class RichText extends Component {
<Fragment>
<TinyMCE
tagName={ Tagname }
onSetup={ this.onSetup }
style={ style }
record={ record }
valueToEditableHTML={ this.valueToEditableHTML }
Expand Down
67 changes: 46 additions & 21 deletions packages/editor/src/components/rich-text/list-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Fragment } from '@wordpress/element';
import {
indentListItems,
outdentListItems,
changeListType,
} from '@wordpress/rich-text';

/**
Expand All @@ -17,20 +18,48 @@ import {
import { RichTextShortcut } from './shortcut';
import BlockFormatControls from '../block-format-controls';

function isListRootSelected( editor ) {
return (
! editor.selection ||
editor.selection.getNode().closest( 'ol,ul' ) === editor.getBody()
);
function isListRootSelected() {
const selection = window.getSelection();

if ( selection.rangeCount === 0 ) {
return true;
}

let { startContainer } = selection.getRangeAt( 0 );

if ( startContainer.nodeType === window.Node.TEXT_NODE ) {
startContainer = startContainer.parentNode;
}

const rootNode = startContainer.closest( '*[contenteditable]' );

if ( ! rootNode || ! rootNode.contains( startContainer ) ) {
return true;
}

return startContainer.closest( 'ol,ul' ) === rootNode;
}

function isActiveListType( editor, tagName, rootTagName ) {
if ( document.activeElement !== editor.getBody() ) {
function isActiveListType( tagName, rootTagName ) {
const selection = window.getSelection();

if ( selection.rangeCount === 0 ) {
return tagName === rootTagName;
}

const listItem = editor.selection.getNode();
const list = listItem.closest( 'ol,ul' );
let { startContainer } = selection.getRangeAt( 0 );

if ( startContainer.nodeType === window.Node.TEXT_NODE ) {
startContainer = startContainer.parentNode;
}

const rootNode = startContainer.closest( '*[contenteditable]' );

if ( ! rootNode || ! rootNode.contains( startContainer ) ) {
return tagName === rootTagName;
}

const list = startContainer.closest( 'ol,ul' );

if ( ! list ) {
return;
Expand All @@ -40,10 +69,8 @@ function isActiveListType( editor, tagName, rootTagName ) {
}

export const ListEdit = ( {
editor,
onTagNameChange,
tagName,
onSyncDOM,
value,
onChange,
} ) => (
Expand Down Expand Up @@ -82,26 +109,24 @@ export const ListEdit = ( {
{
icon: 'editor-ul',
title: __( 'Convert to unordered list' ),
isActive: isActiveListType( editor, 'ul', tagName ),
isActive: isActiveListType( 'ul', tagName ),
onClick() {
if ( isListRootSelected( editor ) ) {
onChange( changeListType( value, { type: 'ul' } ) );

if ( isListRootSelected() ) {
onTagNameChange( 'ul' );
} else {
editor.execCommand( 'InsertUnorderedList' );
onSyncDOM();
}
},
},
{
icon: 'editor-ol',
title: __( 'Convert to ordered list' ),
isActive: isActiveListType( editor, 'ol', tagName ),
isActive: isActiveListType( 'ol', tagName ),
onClick() {
if ( isListRootSelected( editor ) ) {
onChange( changeListType( value, { type: 'ol' } ) );

if ( isListRootSelected() ) {
onTagNameChange( 'ol' );
} else {
editor.execCommand( 'InsertOrderedList' );
onSyncDOM();
}
},
},
Expand Down
5 changes: 0 additions & 5 deletions packages/editor/src/components/rich-text/tinymce.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,11 @@ export default class TinyMCE extends Component {
lists_indent_on_tab: false,
};

if ( multilineTag === 'li' ) {
settings.plugins.push( 'lists' );
}

tinymce.init( {
...settings,
target: this.editorNode,
setup: ( editor ) => {
this.editor = editor;
this.props.onSetup( editor );

// TinyMCE resets the element content on initialization, even
// when it's already identical to what exists currently. This
Expand Down
53 changes: 53 additions & 0 deletions packages/rich-text/src/change-list-type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Internal dependencies
*/

import { LINE_SEPARATOR } from './special-characters';
import { normaliseFormats } from './normalise-formats';

function getLineIndex( { start, text }, startIndex = start ) {
let index = startIndex;

while ( index-- ) {
if ( text[ index ] === LINE_SEPARATOR ) {
return index;
}
}
}

export function changeListType( value, newFormat ) {
const { text, formats, start, end } = value;
const startLineIndex = getLineIndex( value, start );
const endLineIndex = getLineIndex( value, end );
const startLineFormats = formats[ startLineIndex ] || [];
const endLineFormats = formats[ endLineIndex ] || [];
const length = text.length;
const newFormats = formats.slice( 0 );
const startCount = startLineFormats.length - 1;
const endCount = endLineFormats.length - 1;

for ( let index = startLineIndex || 0; index < length; index++ ) {
if ( text[ index ] !== LINE_SEPARATOR ) {
continue;
}

if ( ( newFormats[ index ] || [] ).length <= startCount ) {
break;
}

if ( ! newFormats[ index ] ) {
continue;
}

newFormats[ index ] = newFormats[ index ].map( ( format, i ) => {
return i < startCount || i > endCount ? format : newFormat;
} );
}

return normaliseFormats( {
text,
formats: newFormats,
start,
end,
} );
}
1 change: 1 addition & 0 deletions packages/rich-text/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export { LINE_SEPARATOR } from './special-characters';
export { unregisterFormatType } from './unregister-format-type';
export { indentListItems } from './indent-list-items';
export { outdentListItems } from './outdent-list-items';
export { changeListType } from './change-list-type';

0 comments on commit 794c90e

Please sign in to comment.