From 8dd67ac8417656ebc1cc4362f947852387e68c4e Mon Sep 17 00:00:00 2001 From: iseulde Date: Mon, 3 Jul 2017 22:51:08 +0200 Subject: [PATCH] Add enter patterns --- blocks/editable/patterns.js | 73 ++++++++----------------------- blocks/library/code/index.js | 12 ++++- blocks/library/quote/index.js | 9 ++++ blocks/library/separator/index.js | 12 ++++- 4 files changed, 50 insertions(+), 56 deletions(-) diff --git a/blocks/editable/patterns.js b/blocks/editable/patterns.js index 78774b8d26953e..ebd7f20f479c68 100644 --- a/blocks/editable/patterns.js +++ b/blocks/editable/patterns.js @@ -4,7 +4,7 @@ * External dependencies */ import tinymce from 'tinymce'; -import { find, get, escapeRegExp, trimStart } from 'lodash'; +import { find, get, escapeRegExp, trimStart, partition } from 'lodash'; /** * WordPress dependencies @@ -28,21 +28,15 @@ export default function( editor ) { var VK = tinymce.util.VK; var settings = editor.settings.wptextpattern || {}; - const spacePatterns = getBlockTypes().reduce( ( acc, blockType ) => { + const patterns = getBlockTypes().reduce( ( acc, blockType ) => { const transformsFrom = get( blockType, 'transforms.from', [] ); const transforms = transformsFrom.filter( ( { type } ) => type === 'pattern' ); return [ ...acc, ...transforms ]; }, [] ); - var enterPatterns = settings.enter || [ - // { start: '##', format: 'h2' }, - // { start: '###', format: 'h3' }, - // { start: '####', format: 'h4' }, - // { start: '#####', format: 'h5' }, - // { start: '######', format: 'h6' }, - // { start: '>', format: 'blockquote' }, - // { regExp: /^(-){3,}$/, element: 'hr' } - ]; + const [ enterPatterns, spacePatterns ] = partition( patterns, ( { regExp } ) => + regExp.source.endsWith( '$' ) + ); var inlinePatterns = settings.inline || [ { delimiter: '`', format: 'code' } @@ -209,6 +203,10 @@ export default function( editor ) { } function space() { + if ( ! onReplace ) { + return; + } + var rng = editor.selection.getRng(), node = rng.startContainer, parent, @@ -243,60 +241,27 @@ export default function( editor ) { } function enter() { - var rng = editor.selection.getRng(), - start = rng.startContainer, - node = firstTextNode( start ), - i = enterPatterns.length, - text, pattern, parent; - - if ( ! node ) { + if ( ! onReplace || ! inline ) { return; } - text = node.data; + // Merge text nodes. + editor.getBody().normalize(); - while ( i-- ) { - if ( enterPatterns[ i ].start ) { - if ( text.indexOf( enterPatterns[ i ].start ) === 0 ) { - pattern = enterPatterns[ i ]; - break; - } - } else if ( enterPatterns[ i ].regExp ) { - if ( enterPatterns[ i ].regExp.test( text ) ) { - pattern = enterPatterns[ i ]; - break; - } - } - } + const content = getContent(); - if ( ! pattern ) { + if ( ! content.length ) { return; } - if ( node === start && tinymce.trim( text ) === pattern.start ) { + const pattern = find( enterPatterns, ( { regExp } ) => regExp.test( content[ 0 ] ) ) + + if ( ! pattern ) { return; } - editor.once( 'keyup', function() { - editor.undoManager.add(); - - editor.undoManager.transact( function() { - if ( pattern.format ) { - editor.formatter.apply( pattern.format, {}, node ); - node.replaceData( 0, node.data.length, trimStart( node.data.slice( pattern.start.length ) ) ); - } else if ( pattern.element ) { - parent = node.parentNode && node.parentNode.parentNode; - - if ( parent ) { - parent.replaceChild( document.createElement( pattern.element ), node.parentNode ); - } - } - } ); + const block = pattern.transform( { content } ); - // We need to wait for native events to be triggered. - setTimeout( function() { - canUndo = 'enter'; - } ); - } ); + editor.once( 'keyup', () => onReplace( [ block ] ) ); } } diff --git a/blocks/library/code/index.js b/blocks/library/code/index.js index 4d34e6e1b6619a..d64d8d54af01f7 100644 --- a/blocks/library/code/index.js +++ b/blocks/library/code/index.js @@ -12,7 +12,7 @@ import { __ } from 'i18n'; * Internal dependencies */ import './style.scss'; -import { registerBlockType, query } from '../../api'; +import { registerBlockType, query, createBlock } from '../../api'; const { prop } = query; @@ -27,6 +27,16 @@ registerBlockType( 'core/code', { content: prop( 'code', 'textContent' ), }, + transforms: { + from: [ + { + type: 'pattern', + regExp: /^```$/, + transform: () => createBlock( 'core/code' ), + }, + ], + }, + edit( { attributes, setAttributes, className } ) { return ( \s/, + transform: ( { content } ) => { + return createBlock( 'core/quote', { + value: content, + } ); + }, + }, ], to: [ { diff --git a/blocks/library/separator/index.js b/blocks/library/separator/index.js index a4bc70249bfadb..51c4fb524c7030 100644 --- a/blocks/library/separator/index.js +++ b/blocks/library/separator/index.js @@ -7,7 +7,7 @@ import { __ } from 'i18n'; * Internal dependencies */ import './block.scss'; -import { registerBlockType } from '../../api'; +import { registerBlockType, createBlock } from '../../api'; registerBlockType( 'core/separator', { title: __( 'Separator' ), @@ -16,6 +16,16 @@ registerBlockType( 'core/separator', { category: 'layout', + transforms: { + from: [ + { + type: 'pattern', + regExp: /^-{3,}$/, + transform: () => createBlock( 'core/separator' ), + }, + ], + }, + edit( { className } ) { return
; },