From 850497cb4e2b2b7a25ec9837c816abe7f9cd4fc6 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 15 Mar 2018 17:30:47 +0200 Subject: [PATCH 01/38] Android specific files for the Code block * CSS related imports are suppressed * classnames are left in only to minimize diff among the files but do not play a role, nor style the elements --- blocks/api/factory.android.js | 279 +++++++++++++++++++++++++++ blocks/api/index.android.js | 34 ++++ blocks/library/code/index.android.js | 75 +++++++ blocks/plain-text/index.android.js | 22 +++ 4 files changed, 410 insertions(+) create mode 100644 blocks/api/factory.android.js create mode 100644 blocks/api/index.android.js create mode 100644 blocks/library/code/index.android.js create mode 100644 blocks/plain-text/index.android.js diff --git a/blocks/api/factory.android.js b/blocks/api/factory.android.js new file mode 100644 index 0000000000000..693f15963c3d9 --- /dev/null +++ b/blocks/api/factory.android.js @@ -0,0 +1,279 @@ +/** + * External dependencies + */ +import uuid from 'uuid/v4'; +import { + every, + get, + reduce, + castArray, + findIndex, + includes, + isObjectLike, + filter, + find, + first, + flatMap, + uniqueId, +} from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '../../i18n'; +// import { applyFilters } from '@wordpress/hooks'; + +/** + * Internal dependencies + */ +import { getBlockType, getBlockTypes } from './registration'; + +/** + * Returns a block object given its type and attributes. + * + * @param {string} name Block name. + * @param {Object} blockAttributes Block attributes. + * @param {?Array} innerBlocks Nested blocks. + * + * @return {Object} Block object. + */ +export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { + // Get the type definition associated with a registered block. + const blockType = getBlockType( name ); + + // Ensure attributes contains only values defined by block type, and merge + // default values for missing attributes. + const attributes = reduce( blockType.attributes, ( result, source, key ) => { + const value = blockAttributes[ key ]; + if ( undefined !== value ) { + result[ key ] = value; + } else if ( source.hasOwnProperty( 'default' ) ) { + result[ key ] = source.default; + } + + return result; + }, {} ); + + // Blocks are stored with a unique ID, the assigned type name, + // the block attributes, and their inner blocks. + return { + uid: uuid(), + name, + isValid: true, + attributes, + innerBlocks, + }; +} + +/** + * Given a block object, returns a copy of the block object, optionally merging + * new attributes and/or replacing its inner blocks. + * + * @param {Object} block Block object. + * @param {Object} mergeAttributes Block attributes. + * @param {?Array} innerBlocks Nested blocks. + * + * @return {Object} A cloned block. + */ +export function cloneBlock( block, mergeAttributes = {}, innerBlocks = block.innerBlocks ) { + return { + ...block, + uid: uuid(), + attributes: { + ...block.attributes, + ...mergeAttributes, + }, + innerBlocks, + }; +} + +/** + * Returns a predicate that receives a transformation and returns true if the + * given transformation is able to execute in the situation specified in the + * params. + * + * @param {string} sourceName Block name. + * @param {boolean} isMultiBlock Array of possible block transformations. + * + * @return {Function} Predicate that receives a block type. + */ +const isTransformForBlockSource = ( sourceName, isMultiBlock = false ) => ( transform ) => ( + transform.type === 'block' && + transform.blocks.indexOf( sourceName ) !== -1 && + ( ! isMultiBlock || transform.isMultiBlock ) +); + +/** + * Returns a predicate that receives a block type and returns true if the given + * block type contains a transformation able to execute in the situation + * specified in the params. + * + * @param {string} sourceName Block name. + * @param {boolean} isMultiBlock Array of possible block transformations. + * + * @return {Function} Predicate that receives a block type. + */ +const createIsTypeTransformableFrom = ( sourceName, isMultiBlock = false ) => ( type ) => ( + !! find( + get( type, 'transforms.from', [] ), + isTransformForBlockSource( sourceName, isMultiBlock ), + ) +); + +/** + * Returns an array of possible block transformations that could happen on the + * set of blocks received as argument. + * + * @param {Array} blocks Blocks array. + * + * @return {Array} Array of possible block transformations. + */ +export function getPossibleBlockTransformations( blocks ) { + const sourceBlock = first( blocks ); + if ( ! blocks || ! sourceBlock ) { + return []; + } + const isMultiBlock = blocks.length > 1; + const sourceBlockName = sourceBlock.name; + + if ( isMultiBlock && ! every( blocks, { name: sourceBlockName } ) ) { + return []; + } + + // Compute the block that have a from transformation able to transfer blocks passed as argument. + const blocksToBeTransformedFrom = filter( + getBlockTypes(), + createIsTypeTransformableFrom( sourceBlockName, isMultiBlock ), + ).map( type => type.name ); + + const blockType = getBlockType( sourceBlockName ); + const transformsTo = get( blockType, 'transforms.to', [] ); + + // Generate list of block transformations using the supplied "transforms to". + const blocksToBeTransformedTo = flatMap( + isMultiBlock ? filter( transformsTo, 'isMultiBlock' ) : transformsTo, + transformation => transformation.blocks + ); + + // Returns a unique list of available block transformations. + return reduce( [ + ...blocksToBeTransformedFrom, + ...blocksToBeTransformedTo, + ], ( result, name ) => { + const transformBlockType = getBlockType( name ); + if ( transformBlockType && ! includes( result, transformBlockType ) ) { + result.push( transformBlockType ); + } + return result; + }, [] ); +} + +// /** +// * Switch one or more blocks into one or more blocks of the new block type. +// * +// * @param {Array|Object} blocks Blocks array or block object. +// * @param {string} name Block name. +// * +// * @return {Array} Array of blocks. +// */ +// export function switchToBlockType( blocks, name ) { +// const blocksArray = castArray( blocks ); +// const isMultiBlock = blocksArray.length > 1; +// const firstBlock = blocksArray[ 0 ]; +// const sourceName = firstBlock.name; + +// if ( isMultiBlock && ! every( blocksArray, ( block ) => ( block.name === sourceName ) ) ) { +// return null; +// } + +// // Find the right transformation by giving priority to the "to" +// // transformation. +// const destinationType = getBlockType( name ); +// const sourceType = getBlockType( sourceName ); +// const transformationsFrom = get( destinationType, 'transforms.from', [] ); +// const transformationsTo = get( sourceType, 'transforms.to', [] ); +// const transformation = +// find( +// transformationsTo, +// t => t.type === 'block' && t.blocks.indexOf( name ) !== -1 && ( ! isMultiBlock || t.isMultiBlock ) +// ) || +// find( +// transformationsFrom, +// t => t.type === 'block' && t.blocks.indexOf( sourceName ) !== -1 && ( ! isMultiBlock || t.isMultiBlock ) +// ); + +// // Stop if there is no valid transformation. (How did we get here?) +// if ( ! transformation ) { +// return null; +// } + +// let transformationResults; +// if ( transformation.isMultiBlock ) { +// transformationResults = transformation.transform( blocksArray.map( ( currentBlock ) => currentBlock.attributes ) ); +// } else { +// transformationResults = transformation.transform( firstBlock.attributes ); +// } + +// // Ensure that the transformation function returned an object or an array +// // of objects. +// if ( ! isObjectLike( transformationResults ) ) { +// return null; +// } + +// // If the transformation function returned a single object, we want to work +// // with an array instead. +// transformationResults = castArray( transformationResults ); + +// // Ensure that every block object returned by the transformation has a +// // valid block type. +// if ( transformationResults.some( ( result ) => ! getBlockType( result.name ) ) ) { +// return null; +// } + +// const firstSwitchedBlock = findIndex( transformationResults, ( result ) => result.name === name ); + +// // Ensure that at least one block object returned by the transformation has +// // the expected "destination" block type. +// if ( firstSwitchedBlock < 0 ) { +// return null; +// } + +// return transformationResults.map( ( result, index ) => { +// const transformedBlock = { +// ...result, +// // The first transformed block whose type matches the "destination" +// // type gets to keep the existing UID of the first block. +// uid: index === firstSwitchedBlock ? firstBlock.uid : result.uid, +// }; + +// /** +// * Filters an individual transform result from block transformation. +// * All of the original blocks are passed, since transformations are +// * many-to-many, not one-to-one. +// * +// * @param {Object} transformedBlock The transformed block. +// * @param {Object[]} blocks Original blocks transformed. +// */ +// return applyFilters( 'blocks.switchToBlockType.transformedBlock', transformedBlock, blocks ); +// } ); +// } + +/** + * Creates a new reusable block. + * + * @param {string} type The type of the block referenced by the reusable + * block. + * @param {Object} attributes The attributes of the block referenced by the + * reusable block. + * + * @return {Object} A reusable block object. + */ +export function createReusableBlock( type, attributes ) { + return { + id: -uniqueId(), // Temporary id replaced when the block is saved server side + isTemporary: true, + title: __( 'Untitled block' ), + type, + attributes, + }; +} diff --git a/blocks/api/index.android.js b/blocks/api/index.android.js new file mode 100644 index 0000000000000..a5c666401ecdd --- /dev/null +++ b/blocks/api/index.android.js @@ -0,0 +1,34 @@ +export { + createBlock, + // cloneBlock, + // getPossibleBlockTransformations, + // switchToBlockType, + // createReusableBlock, +} from './factory'; +// export { default as parse, getBlockAttributes } from './parser'; +// export { default as rawHandler } from './raw-handling'; +// export { +// default as serialize, +// getBlockContent, +// getBlockDefaultClassname, +// getSaveElement, +// } from './serializer'; +// export { isValidBlock } from './validation'; +// export { getCategories } from './categories'; +// export { +// registerBlockType, +// unregisterBlockType, +// setUnknownTypeHandlerName, +// getUnknownTypeHandlerName, +// setDefaultBlockName, +// getDefaultBlockName, +// getDefaultBlockForPostFormat, +// getBlockType, +// getBlockTypes, +// getBlockSupport, +// hasBlockSupport, +// isReusableBlock, +// } from './registration'; +// export { +// isUnmodifiedDefaultBlock, +// } from './utils'; diff --git a/blocks/library/code/index.android.js b/blocks/library/code/index.android.js new file mode 100644 index 0000000000000..b88d53d44e5c4 --- /dev/null +++ b/blocks/library/code/index.android.js @@ -0,0 +1,75 @@ +import React from 'react'; +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { __ } from '../../../i18n'; + +/** + * Internal dependencies + */ +// import './editor.scss'; +import PlainText from '../../plain-text'; +// import { createBlock } from '../../api'; + +export const name = 'core/code'; + +export const settings = { + title: __( 'Code' ), + + description: __( 'The code block maintains spaces and tabs, great for showing code snippets.' ), + + icon: 'editor-code', + + category: 'formatting', + + attributes: { + content: { + type: 'string', + source: 'property', + selector: 'code', + property: 'textContent', + }, + }, + + supports: { + html: false, + }, + + transforms: { + from: [ + { + type: 'pattern', + trigger: 'enter', + regExp: /^```$/, + transform: () => createBlock( 'core/code' ), + }, + { + type: 'raw', + isMatch: ( node ) => ( + node.nodeName === 'PRE' && + node.children.length === 1 && + node.firstChild.nodeName === 'CODE' + ), + }, + ], + }, + + edit( { attributes, setAttributes, className } ) { + return ( + + setAttributes( { content } ) } + placeholder={ __( 'Write code…' ) } + aria-label={ __( 'Code' ) } + /> + </View> + ); + }, + + save( { attributes } ) { + return <pre><code>{ attributes.content }</code></pre>; + }, +}; diff --git a/blocks/plain-text/index.android.js b/blocks/plain-text/index.android.js new file mode 100644 index 0000000000000..2d66ccd0942c6 --- /dev/null +++ b/blocks/plain-text/index.android.js @@ -0,0 +1,22 @@ +/** + * External dependencies + */ +import React from 'react'; +import { TextInput } from 'react-native'; +import classnames from 'classnames'; + +/** + * Internal dependencies + */ + +function PlainText( { onChange, className, ...props } ) { + return ( + <TextInput + className={ classnames( 'blocks-plain-text', className ) } + onChangeText={ ( text ) => onChange( text ) } + { ...props } + /> + ); +} + +export default PlainText; From 43590b2a8ac6d1cf6635a85222aab95dae2d969a Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Thu, 15 Mar 2018 17:34:27 +0200 Subject: [PATCH 02/38] Breaking change: Don't override the default JSX translation So far, that's the only way I found to have the android-specific jest tests succeed. --- package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/package.json b/package.json index 21ba6d0adaff8..27486e1cee61a 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,11 @@ "presets": [ "@wordpress/default" ], + "plugins": [ + ["transform-react-jsx", { + "pragma": "React.createElement" + }] + ], "env": { "production": { "plugins": [ From bf82dce16e2ffa6b86abd7603f4c044dfcdcc421 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 19 Mar 2018 12:09:45 +0200 Subject: [PATCH 03/38] Add the platform specific files for iOS as well --- blocks/api/factory.ios.js | 279 +++++++++++++++++++++++++++++++ blocks/api/index.ios.js | 34 ++++ blocks/library/code/index.ios.js | 75 +++++++++ blocks/plain-text/index.ios.js | 22 +++ 4 files changed, 410 insertions(+) create mode 100644 blocks/api/factory.ios.js create mode 100644 blocks/api/index.ios.js create mode 100644 blocks/library/code/index.ios.js create mode 100644 blocks/plain-text/index.ios.js diff --git a/blocks/api/factory.ios.js b/blocks/api/factory.ios.js new file mode 100644 index 0000000000000..693f15963c3d9 --- /dev/null +++ b/blocks/api/factory.ios.js @@ -0,0 +1,279 @@ +/** + * External dependencies + */ +import uuid from 'uuid/v4'; +import { + every, + get, + reduce, + castArray, + findIndex, + includes, + isObjectLike, + filter, + find, + first, + flatMap, + uniqueId, +} from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '../../i18n'; +// import { applyFilters } from '@wordpress/hooks'; + +/** + * Internal dependencies + */ +import { getBlockType, getBlockTypes } from './registration'; + +/** + * Returns a block object given its type and attributes. + * + * @param {string} name Block name. + * @param {Object} blockAttributes Block attributes. + * @param {?Array} innerBlocks Nested blocks. + * + * @return {Object} Block object. + */ +export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { + // Get the type definition associated with a registered block. + const blockType = getBlockType( name ); + + // Ensure attributes contains only values defined by block type, and merge + // default values for missing attributes. + const attributes = reduce( blockType.attributes, ( result, source, key ) => { + const value = blockAttributes[ key ]; + if ( undefined !== value ) { + result[ key ] = value; + } else if ( source.hasOwnProperty( 'default' ) ) { + result[ key ] = source.default; + } + + return result; + }, {} ); + + // Blocks are stored with a unique ID, the assigned type name, + // the block attributes, and their inner blocks. + return { + uid: uuid(), + name, + isValid: true, + attributes, + innerBlocks, + }; +} + +/** + * Given a block object, returns a copy of the block object, optionally merging + * new attributes and/or replacing its inner blocks. + * + * @param {Object} block Block object. + * @param {Object} mergeAttributes Block attributes. + * @param {?Array} innerBlocks Nested blocks. + * + * @return {Object} A cloned block. + */ +export function cloneBlock( block, mergeAttributes = {}, innerBlocks = block.innerBlocks ) { + return { + ...block, + uid: uuid(), + attributes: { + ...block.attributes, + ...mergeAttributes, + }, + innerBlocks, + }; +} + +/** + * Returns a predicate that receives a transformation and returns true if the + * given transformation is able to execute in the situation specified in the + * params. + * + * @param {string} sourceName Block name. + * @param {boolean} isMultiBlock Array of possible block transformations. + * + * @return {Function} Predicate that receives a block type. + */ +const isTransformForBlockSource = ( sourceName, isMultiBlock = false ) => ( transform ) => ( + transform.type === 'block' && + transform.blocks.indexOf( sourceName ) !== -1 && + ( ! isMultiBlock || transform.isMultiBlock ) +); + +/** + * Returns a predicate that receives a block type and returns true if the given + * block type contains a transformation able to execute in the situation + * specified in the params. + * + * @param {string} sourceName Block name. + * @param {boolean} isMultiBlock Array of possible block transformations. + * + * @return {Function} Predicate that receives a block type. + */ +const createIsTypeTransformableFrom = ( sourceName, isMultiBlock = false ) => ( type ) => ( + !! find( + get( type, 'transforms.from', [] ), + isTransformForBlockSource( sourceName, isMultiBlock ), + ) +); + +/** + * Returns an array of possible block transformations that could happen on the + * set of blocks received as argument. + * + * @param {Array} blocks Blocks array. + * + * @return {Array} Array of possible block transformations. + */ +export function getPossibleBlockTransformations( blocks ) { + const sourceBlock = first( blocks ); + if ( ! blocks || ! sourceBlock ) { + return []; + } + const isMultiBlock = blocks.length > 1; + const sourceBlockName = sourceBlock.name; + + if ( isMultiBlock && ! every( blocks, { name: sourceBlockName } ) ) { + return []; + } + + // Compute the block that have a from transformation able to transfer blocks passed as argument. + const blocksToBeTransformedFrom = filter( + getBlockTypes(), + createIsTypeTransformableFrom( sourceBlockName, isMultiBlock ), + ).map( type => type.name ); + + const blockType = getBlockType( sourceBlockName ); + const transformsTo = get( blockType, 'transforms.to', [] ); + + // Generate list of block transformations using the supplied "transforms to". + const blocksToBeTransformedTo = flatMap( + isMultiBlock ? filter( transformsTo, 'isMultiBlock' ) : transformsTo, + transformation => transformation.blocks + ); + + // Returns a unique list of available block transformations. + return reduce( [ + ...blocksToBeTransformedFrom, + ...blocksToBeTransformedTo, + ], ( result, name ) => { + const transformBlockType = getBlockType( name ); + if ( transformBlockType && ! includes( result, transformBlockType ) ) { + result.push( transformBlockType ); + } + return result; + }, [] ); +} + +// /** +// * Switch one or more blocks into one or more blocks of the new block type. +// * +// * @param {Array|Object} blocks Blocks array or block object. +// * @param {string} name Block name. +// * +// * @return {Array} Array of blocks. +// */ +// export function switchToBlockType( blocks, name ) { +// const blocksArray = castArray( blocks ); +// const isMultiBlock = blocksArray.length > 1; +// const firstBlock = blocksArray[ 0 ]; +// const sourceName = firstBlock.name; + +// if ( isMultiBlock && ! every( blocksArray, ( block ) => ( block.name === sourceName ) ) ) { +// return null; +// } + +// // Find the right transformation by giving priority to the "to" +// // transformation. +// const destinationType = getBlockType( name ); +// const sourceType = getBlockType( sourceName ); +// const transformationsFrom = get( destinationType, 'transforms.from', [] ); +// const transformationsTo = get( sourceType, 'transforms.to', [] ); +// const transformation = +// find( +// transformationsTo, +// t => t.type === 'block' && t.blocks.indexOf( name ) !== -1 && ( ! isMultiBlock || t.isMultiBlock ) +// ) || +// find( +// transformationsFrom, +// t => t.type === 'block' && t.blocks.indexOf( sourceName ) !== -1 && ( ! isMultiBlock || t.isMultiBlock ) +// ); + +// // Stop if there is no valid transformation. (How did we get here?) +// if ( ! transformation ) { +// return null; +// } + +// let transformationResults; +// if ( transformation.isMultiBlock ) { +// transformationResults = transformation.transform( blocksArray.map( ( currentBlock ) => currentBlock.attributes ) ); +// } else { +// transformationResults = transformation.transform( firstBlock.attributes ); +// } + +// // Ensure that the transformation function returned an object or an array +// // of objects. +// if ( ! isObjectLike( transformationResults ) ) { +// return null; +// } + +// // If the transformation function returned a single object, we want to work +// // with an array instead. +// transformationResults = castArray( transformationResults ); + +// // Ensure that every block object returned by the transformation has a +// // valid block type. +// if ( transformationResults.some( ( result ) => ! getBlockType( result.name ) ) ) { +// return null; +// } + +// const firstSwitchedBlock = findIndex( transformationResults, ( result ) => result.name === name ); + +// // Ensure that at least one block object returned by the transformation has +// // the expected "destination" block type. +// if ( firstSwitchedBlock < 0 ) { +// return null; +// } + +// return transformationResults.map( ( result, index ) => { +// const transformedBlock = { +// ...result, +// // The first transformed block whose type matches the "destination" +// // type gets to keep the existing UID of the first block. +// uid: index === firstSwitchedBlock ? firstBlock.uid : result.uid, +// }; + +// /** +// * Filters an individual transform result from block transformation. +// * All of the original blocks are passed, since transformations are +// * many-to-many, not one-to-one. +// * +// * @param {Object} transformedBlock The transformed block. +// * @param {Object[]} blocks Original blocks transformed. +// */ +// return applyFilters( 'blocks.switchToBlockType.transformedBlock', transformedBlock, blocks ); +// } ); +// } + +/** + * Creates a new reusable block. + * + * @param {string} type The type of the block referenced by the reusable + * block. + * @param {Object} attributes The attributes of the block referenced by the + * reusable block. + * + * @return {Object} A reusable block object. + */ +export function createReusableBlock( type, attributes ) { + return { + id: -uniqueId(), // Temporary id replaced when the block is saved server side + isTemporary: true, + title: __( 'Untitled block' ), + type, + attributes, + }; +} diff --git a/blocks/api/index.ios.js b/blocks/api/index.ios.js new file mode 100644 index 0000000000000..a5c666401ecdd --- /dev/null +++ b/blocks/api/index.ios.js @@ -0,0 +1,34 @@ +export { + createBlock, + // cloneBlock, + // getPossibleBlockTransformations, + // switchToBlockType, + // createReusableBlock, +} from './factory'; +// export { default as parse, getBlockAttributes } from './parser'; +// export { default as rawHandler } from './raw-handling'; +// export { +// default as serialize, +// getBlockContent, +// getBlockDefaultClassname, +// getSaveElement, +// } from './serializer'; +// export { isValidBlock } from './validation'; +// export { getCategories } from './categories'; +// export { +// registerBlockType, +// unregisterBlockType, +// setUnknownTypeHandlerName, +// getUnknownTypeHandlerName, +// setDefaultBlockName, +// getDefaultBlockName, +// getDefaultBlockForPostFormat, +// getBlockType, +// getBlockTypes, +// getBlockSupport, +// hasBlockSupport, +// isReusableBlock, +// } from './registration'; +// export { +// isUnmodifiedDefaultBlock, +// } from './utils'; diff --git a/blocks/library/code/index.ios.js b/blocks/library/code/index.ios.js new file mode 100644 index 0000000000000..b88d53d44e5c4 --- /dev/null +++ b/blocks/library/code/index.ios.js @@ -0,0 +1,75 @@ +import React from 'react'; +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { __ } from '../../../i18n'; + +/** + * Internal dependencies + */ +// import './editor.scss'; +import PlainText from '../../plain-text'; +// import { createBlock } from '../../api'; + +export const name = 'core/code'; + +export const settings = { + title: __( 'Code' ), + + description: __( 'The code block maintains spaces and tabs, great for showing code snippets.' ), + + icon: 'editor-code', + + category: 'formatting', + + attributes: { + content: { + type: 'string', + source: 'property', + selector: 'code', + property: 'textContent', + }, + }, + + supports: { + html: false, + }, + + transforms: { + from: [ + { + type: 'pattern', + trigger: 'enter', + regExp: /^```$/, + transform: () => createBlock( 'core/code' ), + }, + { + type: 'raw', + isMatch: ( node ) => ( + node.nodeName === 'PRE' && + node.children.length === 1 && + node.firstChild.nodeName === 'CODE' + ), + }, + ], + }, + + edit( { attributes, setAttributes, className } ) { + return ( + <View className={ className }> + <PlainText + value={ attributes.content } + onChange={ ( content ) => setAttributes( { content } ) } + placeholder={ __( 'Write code…' ) } + aria-label={ __( 'Code' ) } + /> + </View> + ); + }, + + save( { attributes } ) { + return <pre><code>{ attributes.content }</code></pre>; + }, +}; diff --git a/blocks/plain-text/index.ios.js b/blocks/plain-text/index.ios.js new file mode 100644 index 0000000000000..2d66ccd0942c6 --- /dev/null +++ b/blocks/plain-text/index.ios.js @@ -0,0 +1,22 @@ +/** + * External dependencies + */ +import React from 'react'; +import { TextInput } from 'react-native'; +import classnames from 'classnames'; + +/** + * Internal dependencies + */ + +function PlainText( { onChange, className, ...props } ) { + return ( + <TextInput + className={ classnames( 'blocks-plain-text', className ) } + onChangeText={ ( text ) => onChange( text ) } + { ...props } + /> + ); +} + +export default PlainText; From 16b7eb5176a1d934f08fdca8128934a6f8e4facd Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Wed, 21 Mar 2018 11:43:24 +0200 Subject: [PATCH 04/38] Set TextInput to multiline for Code block --- blocks/library/code/index.android.js | 1 + blocks/library/code/index.ios.js | 1 + 2 files changed, 2 insertions(+) diff --git a/blocks/library/code/index.android.js b/blocks/library/code/index.android.js index b88d53d44e5c4..c62e286cd3895 100644 --- a/blocks/library/code/index.android.js +++ b/blocks/library/code/index.android.js @@ -61,6 +61,7 @@ export const settings = { <View className={ className }> <PlainText value={ attributes.content } + multiline={ true } onChange={ ( content ) => setAttributes( { content } ) } placeholder={ __( 'Write code…' ) } aria-label={ __( 'Code' ) } diff --git a/blocks/library/code/index.ios.js b/blocks/library/code/index.ios.js index b88d53d44e5c4..c62e286cd3895 100644 --- a/blocks/library/code/index.ios.js +++ b/blocks/library/code/index.ios.js @@ -61,6 +61,7 @@ export const settings = { <View className={ className }> <PlainText value={ attributes.content } + multiline={ true } onChange={ ( content ) => setAttributes( { content } ) } placeholder={ __( 'Write code…' ) } aria-label={ __( 'Code' ) } From 20fd557a8dd1aac70dbd7c8cf8e6b02f08277046 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Wed, 21 Mar 2018 11:47:28 +0200 Subject: [PATCH 05/38] Hide the default TextInput underline on Android --- blocks/library/code/index.android.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/blocks/library/code/index.android.js b/blocks/library/code/index.android.js index c62e286cd3895..e601d582342dd 100644 --- a/blocks/library/code/index.android.js +++ b/blocks/library/code/index.android.js @@ -1,3 +1,5 @@ +/** @format */ + import React from 'react'; import { View } from 'react-native'; @@ -47,11 +49,10 @@ export const settings = { }, { type: 'raw', - isMatch: ( node ) => ( + isMatch: node => node.nodeName === 'PRE' && node.children.length === 1 && - node.firstChild.nodeName === 'CODE' - ), + node.firstChild.nodeName === 'CODE', }, ], }, @@ -62,7 +63,8 @@ export const settings = { <PlainText value={ attributes.content } multiline={ true } - onChange={ ( content ) => setAttributes( { content } ) } + underlineColorAndroid="transparent" + onChange={ content => setAttributes( { content } ) } placeholder={ __( 'Write code…' ) } aria-label={ __( 'Code' ) } /> @@ -71,6 +73,10 @@ export const settings = { }, save( { attributes } ) { - return <pre><code>{ attributes.content }</code></pre>; + return ( + <pre> + <code>{ attributes.content }</code> + </pre> + ); }, }; From f9220442c3e46cbd4c26cf92fca77c2e11ba2c66 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Wed, 21 Mar 2018 16:56:48 +0200 Subject: [PATCH 06/38] Expose registerBlockType, getBlockType to the RN app --- blocks/api/index.android.js | 8 +-- blocks/api/index.ios.js | 8 +-- blocks/library/index.android.js | 99 +++++++++++++++++++++++++++++++++ blocks/library/index.ios.js | 99 +++++++++++++++++++++++++++++++++ 4 files changed, 206 insertions(+), 8 deletions(-) create mode 100644 blocks/library/index.android.js create mode 100644 blocks/library/index.ios.js diff --git a/blocks/api/index.android.js b/blocks/api/index.android.js index a5c666401ecdd..e8da69911a342 100644 --- a/blocks/api/index.android.js +++ b/blocks/api/index.android.js @@ -15,20 +15,20 @@ export { // } from './serializer'; // export { isValidBlock } from './validation'; // export { getCategories } from './categories'; -// export { -// registerBlockType, +export { + registerBlockType, // unregisterBlockType, // setUnknownTypeHandlerName, // getUnknownTypeHandlerName, // setDefaultBlockName, // getDefaultBlockName, // getDefaultBlockForPostFormat, -// getBlockType, + getBlockType, // getBlockTypes, // getBlockSupport, // hasBlockSupport, // isReusableBlock, -// } from './registration'; +} from './registration'; // export { // isUnmodifiedDefaultBlock, // } from './utils'; diff --git a/blocks/api/index.ios.js b/blocks/api/index.ios.js index a5c666401ecdd..e8da69911a342 100644 --- a/blocks/api/index.ios.js +++ b/blocks/api/index.ios.js @@ -15,20 +15,20 @@ export { // } from './serializer'; // export { isValidBlock } from './validation'; // export { getCategories } from './categories'; -// export { -// registerBlockType, +export { + registerBlockType, // unregisterBlockType, // setUnknownTypeHandlerName, // getUnknownTypeHandlerName, // setDefaultBlockName, // getDefaultBlockName, // getDefaultBlockForPostFormat, -// getBlockType, + getBlockType, // getBlockTypes, // getBlockSupport, // hasBlockSupport, // isReusableBlock, -// } from './registration'; +} from './registration'; // export { // isUnmodifiedDefaultBlock, // } from './utils'; diff --git a/blocks/library/index.android.js b/blocks/library/index.android.js new file mode 100644 index 0000000000000..71b6b8eff9c15 --- /dev/null +++ b/blocks/library/index.android.js @@ -0,0 +1,99 @@ +/** + * Internal dependencies + * + * @format + */ +import { + registerBlockType, + // setDefaultBlockName, + // setUnknownTypeHandlerName, +} from '../api'; +// import * as paragraph from './paragraph'; +// import * as image from './image'; +// import * as heading from './heading'; +// import * as quote from './quote'; +// import * as gallery from './gallery'; +// import * as audio from './audio'; +// import * as button from './button'; +// import * as categories from './categories'; +import * as code from './code'; +// import * as columns from './columns'; +// import * as coverImage from './cover-image'; +// import * as embed from './embed'; +// import * as freeform from './freeform'; +// import * as html from './html'; +// import * as latestPosts from './latest-posts'; +// import * as list from './list'; +// import * as more from './more'; +// import * as preformatted from './preformatted'; +// import * as pullquote from './pullquote'; +// import * as reusableBlock from './block'; +// import * as separator from './separator'; +// import * as shortcode from './shortcode'; +// import * as subhead from './subhead'; +// import * as table from './table'; +// import * as textColumns from './text-columns'; +// import * as verse from './verse'; +// import * as video from './video'; + +export const registerCoreBlocks = () => { + [ + // // FIXME: Temporary fix. + // // + // // The Shortcode block declares a catch-all shortcode transform, + // // meaning it will attempt to intercept pastes and block conversions of + // // any valid shortcode-like content. Other blocks (e.g. Gallery) may + // // declare specific shortcode transforms (e.g. `[gallery]`), with which + // // this block would conflict. Thus, the Shortcode block needs to be + // // registered as early as possible, so that any other block types' + // // shortcode transforms can be honoured. + // // + // // This isn't a proper solution, as it is at odds with the + // // specification of shortcode conversion, in the sense that conversion + // // is explicitly independent of block order. Thus, concurrent parse + // // rules (i.e. a same text input can yield two different transforms, + // // like `[gallery] -> { Gallery, Shortcode }`) are unsupported, + // // yielding non-deterministic results. A proper solution could be to + // // let the editor (or site owners) determine a default block handler of + // // unknown shortcodes — see `setUnknownTypeHandlerName`. + // shortcode, + + // // Common blocks are grouped at the top to prioritize their display + // // in various contexts — like the inserter and auto-complete components. + // paragraph, + // image, + // heading, + // gallery, + // list, + // quote, + + // // Register all remaining core blocks. + // audio, + // button, + // categories, + code, + // columns, + // coverImage, + // embed, + // ...embed.common, + // ...embed.others, + // freeform, + // html, + // latestPosts, + // more, + // preformatted, + // pullquote, + // reusableBlock, + // separator, + // subhead, + // table, + // textColumns, + // verse, + // video, + ].forEach( ( { name, settings } ) => { + registerBlockType( name, settings ); + } ); + + // setDefaultBlockName( paragraph.name ); + // setUnknownTypeHandlerName( freeform.name ); +}; diff --git a/blocks/library/index.ios.js b/blocks/library/index.ios.js new file mode 100644 index 0000000000000..71b6b8eff9c15 --- /dev/null +++ b/blocks/library/index.ios.js @@ -0,0 +1,99 @@ +/** + * Internal dependencies + * + * @format + */ +import { + registerBlockType, + // setDefaultBlockName, + // setUnknownTypeHandlerName, +} from '../api'; +// import * as paragraph from './paragraph'; +// import * as image from './image'; +// import * as heading from './heading'; +// import * as quote from './quote'; +// import * as gallery from './gallery'; +// import * as audio from './audio'; +// import * as button from './button'; +// import * as categories from './categories'; +import * as code from './code'; +// import * as columns from './columns'; +// import * as coverImage from './cover-image'; +// import * as embed from './embed'; +// import * as freeform from './freeform'; +// import * as html from './html'; +// import * as latestPosts from './latest-posts'; +// import * as list from './list'; +// import * as more from './more'; +// import * as preformatted from './preformatted'; +// import * as pullquote from './pullquote'; +// import * as reusableBlock from './block'; +// import * as separator from './separator'; +// import * as shortcode from './shortcode'; +// import * as subhead from './subhead'; +// import * as table from './table'; +// import * as textColumns from './text-columns'; +// import * as verse from './verse'; +// import * as video from './video'; + +export const registerCoreBlocks = () => { + [ + // // FIXME: Temporary fix. + // // + // // The Shortcode block declares a catch-all shortcode transform, + // // meaning it will attempt to intercept pastes and block conversions of + // // any valid shortcode-like content. Other blocks (e.g. Gallery) may + // // declare specific shortcode transforms (e.g. `[gallery]`), with which + // // this block would conflict. Thus, the Shortcode block needs to be + // // registered as early as possible, so that any other block types' + // // shortcode transforms can be honoured. + // // + // // This isn't a proper solution, as it is at odds with the + // // specification of shortcode conversion, in the sense that conversion + // // is explicitly independent of block order. Thus, concurrent parse + // // rules (i.e. a same text input can yield two different transforms, + // // like `[gallery] -> { Gallery, Shortcode }`) are unsupported, + // // yielding non-deterministic results. A proper solution could be to + // // let the editor (or site owners) determine a default block handler of + // // unknown shortcodes — see `setUnknownTypeHandlerName`. + // shortcode, + + // // Common blocks are grouped at the top to prioritize their display + // // in various contexts — like the inserter and auto-complete components. + // paragraph, + // image, + // heading, + // gallery, + // list, + // quote, + + // // Register all remaining core blocks. + // audio, + // button, + // categories, + code, + // columns, + // coverImage, + // embed, + // ...embed.common, + // ...embed.others, + // freeform, + // html, + // latestPosts, + // more, + // preformatted, + // pullquote, + // reusableBlock, + // separator, + // subhead, + // table, + // textColumns, + // verse, + // video, + ].forEach( ( { name, settings } ) => { + registerBlockType( name, settings ); + } ); + + // setDefaultBlockName( paragraph.name ); + // setUnknownTypeHandlerName( freeform.name ); +}; From 8ee1a4e2370e5a0b734b68615b0b7d54fc5f6a99 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Wed, 28 Mar 2018 13:02:46 +0300 Subject: [PATCH 07/38] Use .native.js for common native code --- blocks/api/factory.ios.js | 279 ------------------ .../{factory.android.js => factory.native.js} | 0 blocks/api/index.ios.js | 34 --- .../api/{index.android.js => index.native.js} | 32 +- blocks/library/code/index.ios.js | 76 ----- .../{index.android.js => index.native.js} | 0 blocks/library/index.ios.js | 99 ------- .../{index.android.js => index.native.js} | 0 blocks/plain-text/index.ios.js | 22 -- .../{index.android.js => index.native.js} | 0 10 files changed, 16 insertions(+), 526 deletions(-) delete mode 100644 blocks/api/factory.ios.js rename blocks/api/{factory.android.js => factory.native.js} (100%) delete mode 100644 blocks/api/index.ios.js rename blocks/api/{index.android.js => index.native.js} (58%) delete mode 100644 blocks/library/code/index.ios.js rename blocks/library/code/{index.android.js => index.native.js} (100%) delete mode 100644 blocks/library/index.ios.js rename blocks/library/{index.android.js => index.native.js} (100%) delete mode 100644 blocks/plain-text/index.ios.js rename blocks/plain-text/{index.android.js => index.native.js} (100%) diff --git a/blocks/api/factory.ios.js b/blocks/api/factory.ios.js deleted file mode 100644 index 693f15963c3d9..0000000000000 --- a/blocks/api/factory.ios.js +++ /dev/null @@ -1,279 +0,0 @@ -/** - * External dependencies - */ -import uuid from 'uuid/v4'; -import { - every, - get, - reduce, - castArray, - findIndex, - includes, - isObjectLike, - filter, - find, - first, - flatMap, - uniqueId, -} from 'lodash'; - -/** - * WordPress dependencies - */ -import { __ } from '../../i18n'; -// import { applyFilters } from '@wordpress/hooks'; - -/** - * Internal dependencies - */ -import { getBlockType, getBlockTypes } from './registration'; - -/** - * Returns a block object given its type and attributes. - * - * @param {string} name Block name. - * @param {Object} blockAttributes Block attributes. - * @param {?Array} innerBlocks Nested blocks. - * - * @return {Object} Block object. - */ -export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { - // Get the type definition associated with a registered block. - const blockType = getBlockType( name ); - - // Ensure attributes contains only values defined by block type, and merge - // default values for missing attributes. - const attributes = reduce( blockType.attributes, ( result, source, key ) => { - const value = blockAttributes[ key ]; - if ( undefined !== value ) { - result[ key ] = value; - } else if ( source.hasOwnProperty( 'default' ) ) { - result[ key ] = source.default; - } - - return result; - }, {} ); - - // Blocks are stored with a unique ID, the assigned type name, - // the block attributes, and their inner blocks. - return { - uid: uuid(), - name, - isValid: true, - attributes, - innerBlocks, - }; -} - -/** - * Given a block object, returns a copy of the block object, optionally merging - * new attributes and/or replacing its inner blocks. - * - * @param {Object} block Block object. - * @param {Object} mergeAttributes Block attributes. - * @param {?Array} innerBlocks Nested blocks. - * - * @return {Object} A cloned block. - */ -export function cloneBlock( block, mergeAttributes = {}, innerBlocks = block.innerBlocks ) { - return { - ...block, - uid: uuid(), - attributes: { - ...block.attributes, - ...mergeAttributes, - }, - innerBlocks, - }; -} - -/** - * Returns a predicate that receives a transformation and returns true if the - * given transformation is able to execute in the situation specified in the - * params. - * - * @param {string} sourceName Block name. - * @param {boolean} isMultiBlock Array of possible block transformations. - * - * @return {Function} Predicate that receives a block type. - */ -const isTransformForBlockSource = ( sourceName, isMultiBlock = false ) => ( transform ) => ( - transform.type === 'block' && - transform.blocks.indexOf( sourceName ) !== -1 && - ( ! isMultiBlock || transform.isMultiBlock ) -); - -/** - * Returns a predicate that receives a block type and returns true if the given - * block type contains a transformation able to execute in the situation - * specified in the params. - * - * @param {string} sourceName Block name. - * @param {boolean} isMultiBlock Array of possible block transformations. - * - * @return {Function} Predicate that receives a block type. - */ -const createIsTypeTransformableFrom = ( sourceName, isMultiBlock = false ) => ( type ) => ( - !! find( - get( type, 'transforms.from', [] ), - isTransformForBlockSource( sourceName, isMultiBlock ), - ) -); - -/** - * Returns an array of possible block transformations that could happen on the - * set of blocks received as argument. - * - * @param {Array} blocks Blocks array. - * - * @return {Array} Array of possible block transformations. - */ -export function getPossibleBlockTransformations( blocks ) { - const sourceBlock = first( blocks ); - if ( ! blocks || ! sourceBlock ) { - return []; - } - const isMultiBlock = blocks.length > 1; - const sourceBlockName = sourceBlock.name; - - if ( isMultiBlock && ! every( blocks, { name: sourceBlockName } ) ) { - return []; - } - - // Compute the block that have a from transformation able to transfer blocks passed as argument. - const blocksToBeTransformedFrom = filter( - getBlockTypes(), - createIsTypeTransformableFrom( sourceBlockName, isMultiBlock ), - ).map( type => type.name ); - - const blockType = getBlockType( sourceBlockName ); - const transformsTo = get( blockType, 'transforms.to', [] ); - - // Generate list of block transformations using the supplied "transforms to". - const blocksToBeTransformedTo = flatMap( - isMultiBlock ? filter( transformsTo, 'isMultiBlock' ) : transformsTo, - transformation => transformation.blocks - ); - - // Returns a unique list of available block transformations. - return reduce( [ - ...blocksToBeTransformedFrom, - ...blocksToBeTransformedTo, - ], ( result, name ) => { - const transformBlockType = getBlockType( name ); - if ( transformBlockType && ! includes( result, transformBlockType ) ) { - result.push( transformBlockType ); - } - return result; - }, [] ); -} - -// /** -// * Switch one or more blocks into one or more blocks of the new block type. -// * -// * @param {Array|Object} blocks Blocks array or block object. -// * @param {string} name Block name. -// * -// * @return {Array} Array of blocks. -// */ -// export function switchToBlockType( blocks, name ) { -// const blocksArray = castArray( blocks ); -// const isMultiBlock = blocksArray.length > 1; -// const firstBlock = blocksArray[ 0 ]; -// const sourceName = firstBlock.name; - -// if ( isMultiBlock && ! every( blocksArray, ( block ) => ( block.name === sourceName ) ) ) { -// return null; -// } - -// // Find the right transformation by giving priority to the "to" -// // transformation. -// const destinationType = getBlockType( name ); -// const sourceType = getBlockType( sourceName ); -// const transformationsFrom = get( destinationType, 'transforms.from', [] ); -// const transformationsTo = get( sourceType, 'transforms.to', [] ); -// const transformation = -// find( -// transformationsTo, -// t => t.type === 'block' && t.blocks.indexOf( name ) !== -1 && ( ! isMultiBlock || t.isMultiBlock ) -// ) || -// find( -// transformationsFrom, -// t => t.type === 'block' && t.blocks.indexOf( sourceName ) !== -1 && ( ! isMultiBlock || t.isMultiBlock ) -// ); - -// // Stop if there is no valid transformation. (How did we get here?) -// if ( ! transformation ) { -// return null; -// } - -// let transformationResults; -// if ( transformation.isMultiBlock ) { -// transformationResults = transformation.transform( blocksArray.map( ( currentBlock ) => currentBlock.attributes ) ); -// } else { -// transformationResults = transformation.transform( firstBlock.attributes ); -// } - -// // Ensure that the transformation function returned an object or an array -// // of objects. -// if ( ! isObjectLike( transformationResults ) ) { -// return null; -// } - -// // If the transformation function returned a single object, we want to work -// // with an array instead. -// transformationResults = castArray( transformationResults ); - -// // Ensure that every block object returned by the transformation has a -// // valid block type. -// if ( transformationResults.some( ( result ) => ! getBlockType( result.name ) ) ) { -// return null; -// } - -// const firstSwitchedBlock = findIndex( transformationResults, ( result ) => result.name === name ); - -// // Ensure that at least one block object returned by the transformation has -// // the expected "destination" block type. -// if ( firstSwitchedBlock < 0 ) { -// return null; -// } - -// return transformationResults.map( ( result, index ) => { -// const transformedBlock = { -// ...result, -// // The first transformed block whose type matches the "destination" -// // type gets to keep the existing UID of the first block. -// uid: index === firstSwitchedBlock ? firstBlock.uid : result.uid, -// }; - -// /** -// * Filters an individual transform result from block transformation. -// * All of the original blocks are passed, since transformations are -// * many-to-many, not one-to-one. -// * -// * @param {Object} transformedBlock The transformed block. -// * @param {Object[]} blocks Original blocks transformed. -// */ -// return applyFilters( 'blocks.switchToBlockType.transformedBlock', transformedBlock, blocks ); -// } ); -// } - -/** - * Creates a new reusable block. - * - * @param {string} type The type of the block referenced by the reusable - * block. - * @param {Object} attributes The attributes of the block referenced by the - * reusable block. - * - * @return {Object} A reusable block object. - */ -export function createReusableBlock( type, attributes ) { - return { - id: -uniqueId(), // Temporary id replaced when the block is saved server side - isTemporary: true, - title: __( 'Untitled block' ), - type, - attributes, - }; -} diff --git a/blocks/api/factory.android.js b/blocks/api/factory.native.js similarity index 100% rename from blocks/api/factory.android.js rename to blocks/api/factory.native.js diff --git a/blocks/api/index.ios.js b/blocks/api/index.ios.js deleted file mode 100644 index e8da69911a342..0000000000000 --- a/blocks/api/index.ios.js +++ /dev/null @@ -1,34 +0,0 @@ -export { - createBlock, - // cloneBlock, - // getPossibleBlockTransformations, - // switchToBlockType, - // createReusableBlock, -} from './factory'; -// export { default as parse, getBlockAttributes } from './parser'; -// export { default as rawHandler } from './raw-handling'; -// export { -// default as serialize, -// getBlockContent, -// getBlockDefaultClassname, -// getSaveElement, -// } from './serializer'; -// export { isValidBlock } from './validation'; -// export { getCategories } from './categories'; -export { - registerBlockType, -// unregisterBlockType, -// setUnknownTypeHandlerName, -// getUnknownTypeHandlerName, -// setDefaultBlockName, -// getDefaultBlockName, -// getDefaultBlockForPostFormat, - getBlockType, -// getBlockTypes, -// getBlockSupport, -// hasBlockSupport, -// isReusableBlock, -} from './registration'; -// export { -// isUnmodifiedDefaultBlock, -// } from './utils'; diff --git a/blocks/api/index.android.js b/blocks/api/index.native.js similarity index 58% rename from blocks/api/index.android.js rename to blocks/api/index.native.js index e8da69911a342..c19e527e60d26 100644 --- a/blocks/api/index.android.js +++ b/blocks/api/index.native.js @@ -1,10 +1,10 @@ -export { - createBlock, - // cloneBlock, - // getPossibleBlockTransformations, - // switchToBlockType, - // createReusableBlock, -} from './factory'; +/** @format */ + +// cloneBlock, +export { createBlock } from // getPossibleBlockTransformations, +// switchToBlockType, +// createReusableBlock, +'./factory'; // export { default as parse, getBlockAttributes } from './parser'; // export { default as rawHandler } from './raw-handling'; // export { @@ -15,20 +15,20 @@ export { // } from './serializer'; // export { isValidBlock } from './validation'; // export { getCategories } from './categories'; +// getBlockTypes, export { registerBlockType, -// unregisterBlockType, -// setUnknownTypeHandlerName, -// getUnknownTypeHandlerName, -// setDefaultBlockName, -// getDefaultBlockName, -// getDefaultBlockForPostFormat, + // unregisterBlockType, + // setUnknownTypeHandlerName, + // getUnknownTypeHandlerName, + // setDefaultBlockName, + // getDefaultBlockName, + // getDefaultBlockForPostFormat, getBlockType, -// getBlockTypes, -// getBlockSupport, +} from // getBlockSupport, // hasBlockSupport, // isReusableBlock, -} from './registration'; +'./registration'; // export { // isUnmodifiedDefaultBlock, // } from './utils'; diff --git a/blocks/library/code/index.ios.js b/blocks/library/code/index.ios.js deleted file mode 100644 index c62e286cd3895..0000000000000 --- a/blocks/library/code/index.ios.js +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import { View } from 'react-native'; - -/** - * WordPress dependencies - */ -import { __ } from '../../../i18n'; - -/** - * Internal dependencies - */ -// import './editor.scss'; -import PlainText from '../../plain-text'; -// import { createBlock } from '../../api'; - -export const name = 'core/code'; - -export const settings = { - title: __( 'Code' ), - - description: __( 'The code block maintains spaces and tabs, great for showing code snippets.' ), - - icon: 'editor-code', - - category: 'formatting', - - attributes: { - content: { - type: 'string', - source: 'property', - selector: 'code', - property: 'textContent', - }, - }, - - supports: { - html: false, - }, - - transforms: { - from: [ - { - type: 'pattern', - trigger: 'enter', - regExp: /^```$/, - transform: () => createBlock( 'core/code' ), - }, - { - type: 'raw', - isMatch: ( node ) => ( - node.nodeName === 'PRE' && - node.children.length === 1 && - node.firstChild.nodeName === 'CODE' - ), - }, - ], - }, - - edit( { attributes, setAttributes, className } ) { - return ( - <View className={ className }> - <PlainText - value={ attributes.content } - multiline={ true } - onChange={ ( content ) => setAttributes( { content } ) } - placeholder={ __( 'Write code…' ) } - aria-label={ __( 'Code' ) } - /> - </View> - ); - }, - - save( { attributes } ) { - return <pre><code>{ attributes.content }</code></pre>; - }, -}; diff --git a/blocks/library/code/index.android.js b/blocks/library/code/index.native.js similarity index 100% rename from blocks/library/code/index.android.js rename to blocks/library/code/index.native.js diff --git a/blocks/library/index.ios.js b/blocks/library/index.ios.js deleted file mode 100644 index 71b6b8eff9c15..0000000000000 --- a/blocks/library/index.ios.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Internal dependencies - * - * @format - */ -import { - registerBlockType, - // setDefaultBlockName, - // setUnknownTypeHandlerName, -} from '../api'; -// import * as paragraph from './paragraph'; -// import * as image from './image'; -// import * as heading from './heading'; -// import * as quote from './quote'; -// import * as gallery from './gallery'; -// import * as audio from './audio'; -// import * as button from './button'; -// import * as categories from './categories'; -import * as code from './code'; -// import * as columns from './columns'; -// import * as coverImage from './cover-image'; -// import * as embed from './embed'; -// import * as freeform from './freeform'; -// import * as html from './html'; -// import * as latestPosts from './latest-posts'; -// import * as list from './list'; -// import * as more from './more'; -// import * as preformatted from './preformatted'; -// import * as pullquote from './pullquote'; -// import * as reusableBlock from './block'; -// import * as separator from './separator'; -// import * as shortcode from './shortcode'; -// import * as subhead from './subhead'; -// import * as table from './table'; -// import * as textColumns from './text-columns'; -// import * as verse from './verse'; -// import * as video from './video'; - -export const registerCoreBlocks = () => { - [ - // // FIXME: Temporary fix. - // // - // // The Shortcode block declares a catch-all shortcode transform, - // // meaning it will attempt to intercept pastes and block conversions of - // // any valid shortcode-like content. Other blocks (e.g. Gallery) may - // // declare specific shortcode transforms (e.g. `[gallery]`), with which - // // this block would conflict. Thus, the Shortcode block needs to be - // // registered as early as possible, so that any other block types' - // // shortcode transforms can be honoured. - // // - // // This isn't a proper solution, as it is at odds with the - // // specification of shortcode conversion, in the sense that conversion - // // is explicitly independent of block order. Thus, concurrent parse - // // rules (i.e. a same text input can yield two different transforms, - // // like `[gallery] -> { Gallery, Shortcode }`) are unsupported, - // // yielding non-deterministic results. A proper solution could be to - // // let the editor (or site owners) determine a default block handler of - // // unknown shortcodes — see `setUnknownTypeHandlerName`. - // shortcode, - - // // Common blocks are grouped at the top to prioritize their display - // // in various contexts — like the inserter and auto-complete components. - // paragraph, - // image, - // heading, - // gallery, - // list, - // quote, - - // // Register all remaining core blocks. - // audio, - // button, - // categories, - code, - // columns, - // coverImage, - // embed, - // ...embed.common, - // ...embed.others, - // freeform, - // html, - // latestPosts, - // more, - // preformatted, - // pullquote, - // reusableBlock, - // separator, - // subhead, - // table, - // textColumns, - // verse, - // video, - ].forEach( ( { name, settings } ) => { - registerBlockType( name, settings ); - } ); - - // setDefaultBlockName( paragraph.name ); - // setUnknownTypeHandlerName( freeform.name ); -}; diff --git a/blocks/library/index.android.js b/blocks/library/index.native.js similarity index 100% rename from blocks/library/index.android.js rename to blocks/library/index.native.js diff --git a/blocks/plain-text/index.ios.js b/blocks/plain-text/index.ios.js deleted file mode 100644 index 2d66ccd0942c6..0000000000000 --- a/blocks/plain-text/index.ios.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * External dependencies - */ -import React from 'react'; -import { TextInput } from 'react-native'; -import classnames from 'classnames'; - -/** - * Internal dependencies - */ - -function PlainText( { onChange, className, ...props } ) { - return ( - <TextInput - className={ classnames( 'blocks-plain-text', className ) } - onChangeText={ ( text ) => onChange( text ) } - { ...props } - /> - ); -} - -export default PlainText; diff --git a/blocks/plain-text/index.android.js b/blocks/plain-text/index.native.js similarity index 100% rename from blocks/plain-text/index.android.js rename to blocks/plain-text/index.native.js From 9a2c431b5bbba2653b347b86462c065401920814 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Wed, 28 Mar 2018 15:08:29 +0300 Subject: [PATCH 08/38] Correct configuration for the babel plugins settings --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7f7e7b05f4979..35594975d7eec 100644 --- a/package.json +++ b/package.json @@ -102,11 +102,11 @@ ], "plugins": [ [ - "transform-async-generator-functions", - "transform-react-jsx", { - "pragma": "React.createElement" - } - ] + "transform-async-generator-functions" + ], + [ "transform-react-jsx", { + "pragma": "React.createElement" + } ] ], "env": { "production": { From 0f3b9ea62f9236517a90763263d3b7e45c47ce17 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Wed, 28 Mar 2018 15:10:01 +0300 Subject: [PATCH 09/38] transform-react-jsx for the production env as well --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 35594975d7eec..46a84bf8590e4 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,10 @@ "output": "languages/gutenberg.pot" } ], - "transform-async-generator-functions" + "transform-async-generator-functions", + [ "transform-react-jsx", { + "pragma": "React.createElement" + } ] ] } } From 0aaba3dab9a8c3869b5991495f2c845bf79f05af Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Thu, 29 Mar 2018 03:21:17 +0300 Subject: [PATCH 10/38] No need for pragma override Will define a `wp` global via RN and reuse the `createElement()` from `@gutenberg/component`. --- package.json | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 46a84bf8590e4..0c285c6b5f6b2 100644 --- a/package.json +++ b/package.json @@ -101,12 +101,7 @@ "@wordpress/default" ], "plugins": [ - [ - "transform-async-generator-functions" - ], - [ "transform-react-jsx", { - "pragma": "React.createElement" - } ] + "transform-async-generator-functions" ], "env": { "production": { @@ -117,10 +112,7 @@ "output": "languages/gutenberg.pot" } ], - "transform-async-generator-functions", - [ "transform-react-jsx", { - "pragma": "React.createElement" - } ] + "transform-async-generator-functions" ] } } From a3d5ab4af34941e5afb12eba3b620dce565a78e6 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Thu, 29 Mar 2018 03:44:08 +0300 Subject: [PATCH 11/38] Ignore mobile native files when linting --- .eslintignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintignore b/.eslintignore index 8fe28b3d6ebc9..25dbbfd06d9c0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,3 +2,6 @@ build coverage node_modules vendor +*.native.js +*.android.js +*.ios.js \ No newline at end of file From a29e5bcc640fa466328745918cb1321216e8e75c Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 30 Mar 2018 14:54:00 +0300 Subject: [PATCH 12/38] Revert "Ignore mobile native files when linting" This reverts commit a3d5ab4af34941e5afb12eba3b620dce565a78e6. --- .eslintignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.eslintignore b/.eslintignore index 25dbbfd06d9c0..8fe28b3d6ebc9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,6 +2,3 @@ build coverage node_modules vendor -*.native.js -*.android.js -*.ios.js \ No newline at end of file From e37c8bc2f8b1c44beed94c92b34efc54a7842f5f Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 30 Mar 2018 14:56:10 +0300 Subject: [PATCH 13/38] Comment out ununsed imports --- blocks/api/factory.native.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blocks/api/factory.native.js b/blocks/api/factory.native.js index 693f15963c3d9..febe979253bba 100644 --- a/blocks/api/factory.native.js +++ b/blocks/api/factory.native.js @@ -6,10 +6,10 @@ import { every, get, reduce, - castArray, - findIndex, + // castArray, + // findIndex, includes, - isObjectLike, + // isObjectLike, filter, find, first, From a6f8089b736774cbf9f42f34a9022e87ab648525 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 30 Mar 2018 14:56:46 +0300 Subject: [PATCH 14/38] Fix codestyle --- blocks/api/index.native.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/blocks/api/index.native.js b/blocks/api/index.native.js index c19e527e60d26..87d7724ad127c 100644 --- a/blocks/api/index.native.js +++ b/blocks/api/index.native.js @@ -4,7 +4,7 @@ export { createBlock } from // getPossibleBlockTransformations, // switchToBlockType, // createReusableBlock, -'./factory'; + './factory'; // export { default as parse, getBlockAttributes } from './parser'; // export { default as rawHandler } from './raw-handling'; // export { @@ -25,10 +25,11 @@ export { // getDefaultBlockName, // getDefaultBlockForPostFormat, getBlockType, -} from // getBlockSupport, -// hasBlockSupport, -// isReusableBlock, -'./registration'; + // getBlockSupport, + // hasBlockSupport, + // isReusableBlock, +} from + './registration'; // export { // isUnmodifiedDefaultBlock, // } from './utils'; From c190e24fb1da4f0f6b2b0a376336b88c090cde56 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 30 Mar 2018 14:57:22 +0300 Subject: [PATCH 15/38] Import is compatible anyway, uncomment it --- blocks/library/code/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/library/code/index.native.js b/blocks/library/code/index.native.js index e601d582342dd..df701f11570be 100644 --- a/blocks/library/code/index.native.js +++ b/blocks/library/code/index.native.js @@ -13,7 +13,7 @@ import { __ } from '../../../i18n'; */ // import './editor.scss'; import PlainText from '../../plain-text'; -// import { createBlock } from '../../api'; +import { createBlock } from '../../api'; export const name = 'core/code'; From c96b10bf06c6cd9099085f3d2e8536fe2743230a Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 30 Mar 2018 14:58:05 +0300 Subject: [PATCH 16/38] Remove the React import. The RN project auto-imports it. --- blocks/library/code/index.native.js | 1 - blocks/plain-text/index.native.js | 1 - 2 files changed, 2 deletions(-) diff --git a/blocks/library/code/index.native.js b/blocks/library/code/index.native.js index df701f11570be..bde63a6af1b97 100644 --- a/blocks/library/code/index.native.js +++ b/blocks/library/code/index.native.js @@ -1,6 +1,5 @@ /** @format */ -import React from 'react'; import { View } from 'react-native'; /** diff --git a/blocks/plain-text/index.native.js b/blocks/plain-text/index.native.js index 2d66ccd0942c6..63a01eb2b1ef8 100644 --- a/blocks/plain-text/index.native.js +++ b/blocks/plain-text/index.native.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import React from 'react'; import { TextInput } from 'react-native'; import classnames from 'classnames'; From 685d17886f1922559d507599c564e2f2cf3be884 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 30 Mar 2018 16:45:13 +0300 Subject: [PATCH 17/38] Limit native code to the edit function alone --- blocks/library/code/edit.js | 23 ++++++++ blocks/library/code/edit.native.js | 29 +++++++++++ blocks/library/code/index.js | 16 +----- blocks/library/code/index.native.js | 81 ----------------------------- 4 files changed, 54 insertions(+), 95 deletions(-) create mode 100644 blocks/library/code/edit.js create mode 100644 blocks/library/code/edit.native.js delete mode 100644 blocks/library/code/index.native.js diff --git a/blocks/library/code/edit.js b/blocks/library/code/edit.js new file mode 100644 index 0000000000000..b5b38ac74487a --- /dev/null +++ b/blocks/library/code/edit.js @@ -0,0 +1,23 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import './editor.scss'; +import PlainText from '../../plain-text'; + +export function edit( { attributes, setAttributes, className } ) { + return ( + <div className={ className }> + <PlainText + value={ attributes.content } + onChange={ ( content ) => setAttributes( { content } ) } + placeholder={ __( 'Write code…' ) } + aria-label={ __( 'Code' ) } + /> + </div> + ); +} diff --git a/blocks/library/code/edit.native.js b/blocks/library/code/edit.native.js new file mode 100644 index 0000000000000..4d722e20e88cf --- /dev/null +++ b/blocks/library/code/edit.native.js @@ -0,0 +1,29 @@ +/** @format */ + +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { __ } from '../../../i18n'; + +/** + * Internal dependencies + */ +import PlainText from '../../plain-text'; + +export function edit( { attributes, setAttributes, className } ) { + return ( + <View className={ className }> + <PlainText + value={ attributes.content } + multiline={ true } + underlineColorAndroid="transparent" + onChange={ content => setAttributes( { content } ) } + placeholder={ __( 'Write code…' ) } + aria-label={ __( 'Code' ) } + /> + </View> + ); +} + diff --git a/blocks/library/code/index.js b/blocks/library/code/index.js index cf40be5028f01..d2a1cfca1b0c5 100644 --- a/blocks/library/code/index.js +++ b/blocks/library/code/index.js @@ -6,9 +6,8 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import './editor.scss'; -import PlainText from '../../plain-text'; import { createBlock } from '../../api'; +import { edit } from './edit'; export const name = 'core/code'; @@ -53,18 +52,7 @@ export const settings = { ], }, - edit( { attributes, setAttributes, className } ) { - return ( - <div className={ className }> - <PlainText - value={ attributes.content } - onChange={ ( content ) => setAttributes( { content } ) } - placeholder={ __( 'Write code…' ) } - aria-label={ __( 'Code' ) } - /> - </div> - ); - }, + edit: edit, save( { attributes } ) { return <pre><code>{ attributes.content }</code></pre>; diff --git a/blocks/library/code/index.native.js b/blocks/library/code/index.native.js deleted file mode 100644 index bde63a6af1b97..0000000000000 --- a/blocks/library/code/index.native.js +++ /dev/null @@ -1,81 +0,0 @@ -/** @format */ - -import { View } from 'react-native'; - -/** - * WordPress dependencies - */ -import { __ } from '../../../i18n'; - -/** - * Internal dependencies - */ -// import './editor.scss'; -import PlainText from '../../plain-text'; -import { createBlock } from '../../api'; - -export const name = 'core/code'; - -export const settings = { - title: __( 'Code' ), - - description: __( 'The code block maintains spaces and tabs, great for showing code snippets.' ), - - icon: 'editor-code', - - category: 'formatting', - - attributes: { - content: { - type: 'string', - source: 'property', - selector: 'code', - property: 'textContent', - }, - }, - - supports: { - html: false, - }, - - transforms: { - from: [ - { - type: 'pattern', - trigger: 'enter', - regExp: /^```$/, - transform: () => createBlock( 'core/code' ), - }, - { - type: 'raw', - isMatch: node => - node.nodeName === 'PRE' && - node.children.length === 1 && - node.firstChild.nodeName === 'CODE', - }, - ], - }, - - edit( { attributes, setAttributes, className } ) { - return ( - <View className={ className }> - <PlainText - value={ attributes.content } - multiline={ true } - underlineColorAndroid="transparent" - onChange={ content => setAttributes( { content } ) } - placeholder={ __( 'Write code…' ) } - aria-label={ __( 'Code' ) } - /> - </View> - ); - }, - - save( { attributes } ) { - return ( - <pre> - <code>{ attributes.content }</code> - </pre> - ); - }, -}; From ad934ad284d3a6e447f0eef887e8dc6ff9af0b8c Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Thu, 5 Apr 2018 01:16:54 +0300 Subject: [PATCH 18/38] Expose getBlockContent to RN --- blocks/api/index.native.js | 7 +- element/index.native.js | 232 +++++++++++++++++++++++++++++++++++++ utils/index.native.js | 16 +++ 3 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 element/index.native.js create mode 100644 utils/index.native.js diff --git a/blocks/api/index.native.js b/blocks/api/index.native.js index 87d7724ad127c..24febf805478a 100644 --- a/blocks/api/index.native.js +++ b/blocks/api/index.native.js @@ -7,12 +7,13 @@ export { createBlock } from // getPossibleBlockTransformations, './factory'; // export { default as parse, getBlockAttributes } from './parser'; // export { default as rawHandler } from './raw-handling'; -// export { +export { // default as serialize, -// getBlockContent, + getBlockContent, // getBlockDefaultClassname, // getSaveElement, -// } from './serializer'; +} from + './serializer'; // export { isValidBlock } from './validation'; // export { getCategories } from './categories'; // getBlockTypes, diff --git a/element/index.native.js b/element/index.native.js new file mode 100644 index 0000000000000..d4ecb8de5aa97 --- /dev/null +++ b/element/index.native.js @@ -0,0 +1,232 @@ +/** + * External dependencies + */ +import { + // createContext, + createElement, + Component, + // cloneElement, + // Children, + // Fragment +} from 'react'; +// import { render, findDOMNode, createPortal, unmountComponentAtNode } from 'react-dom'; +import { + // camelCase, + // flowRight, + // isString, + // upperFirst, + isEmpty, +} from 'lodash'; + +/** + * WordPress dependencies + */ +// import { deprecated } from '@wordpress/utils'; + +/** + * Internal dependencies + */ +import serialize from './serialize'; + +/** + * Returns a new element of given type. Type can be either a string tag name or + * another function which itself returns an element. + * + * @param {?(string|Function)} type Tag name or element creator + * @param {Object} props Element properties, either attribute + * set to apply to DOM node or values to + * pass through to element creator + * @param {...WPElement} children Descendant elements + * + * @return {WPElement} Element. + */ +// export { createElement }; + +/** + * Renders a given element into the target DOM node. + * + * @param {WPElement} element Element to render + * @param {Element} target DOM node into which element should be rendered + */ +// export { render }; + +/** + * Removes any mounted element from the target DOM node. + * + * @param {Element} target DOM node in which element is to be removed + */ +// export { unmountComponentAtNode }; + +/** + * A base class to create WordPress Components (Refs, state and lifecycle hooks) + */ +export { Component }; + +/** + * Creates a copy of an element with extended props. + * + * @param {WPElement} element Element + * @param {?Object} props Props to apply to cloned element + * + * @return {WPElement} Cloned element. + */ +// export { cloneElement }; + +/** + * Finds the dom node of a React component + * + * @param {Component} component component's instance + * @param {Element} target DOM node into which element should be rendered + */ +// export { findDOMNode }; + +// export { Children }; + +/** + * A component which renders its children without any wrapping element. + */ +// export { Fragment }; + +/** + * Creates a context object containing two components: a provider and consumer. + * + * @param {Object} defaultValue Data stored in the context. + * + * @return {Object} Context object. + */ +// export { createContext }; + +/** + * Creates a portal into which a component can be rendered. + * + * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235 + * + * @param {Component} component Component + * @param {Element} target DOM node into which element should be rendered + */ +// export { createPortal }; + +/** + * Renders a given element into a string. + * + * @param {WPElement} element Element to render + * + * @return {string} HTML. + */ +export { serialize as renderToString }; + +/** + * Concatenate two or more React children objects. + * + * @param {...?Object} childrenArguments Array of children arguments (array of arrays/strings/objects) to concatenate. + * + * @return {Array} The concatenated value. + */ +// export function concatChildren( ...childrenArguments ) { +// return childrenArguments.reduce( ( memo, children, i ) => { +// Children.forEach( children, ( child, j ) => { +// if ( child && 'string' !== typeof child ) { +// child = cloneElement( child, { +// key: [ i, j ].join(), +// } ); +// } + +// memo.push( child ); +// } ); + +// return memo; +// }, [] ); +// } + +/** + * Switches the nodeName of all the elements in the children object. + * + * @param {?Object} children Children object. + * @param {string} nodeName Node name. + * + * @return {?Object} The updated children object. + */ +// export function switchChildrenNodeName( children, nodeName ) { +// return children && Children.map( children, ( elt, index ) => { +// if ( isString( elt ) ) { +// return createElement( nodeName, { key: index }, elt ); +// } +// const { children: childrenProp, ...props } = elt.props; +// return createElement( nodeName, { key: index, ...props }, childrenProp ); +// } ); +// } + +/** + * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function + * composition, where each successive invocation is supplied the return value of the previous. + * + * @param {...Function} hocs The HOC functions to invoke. + * + * @return {Function} Returns the new composite function. + */ +// export { flowRight as compose }; + +/** + * Returns a wrapped version of a React component's display name. + * Higher-order components use getWrapperDisplayName(). + * + * @param {Function|Component} BaseComponent Used to detect the existing display name. + * @param {string} wrapperName Wrapper name to prepend to the display name. + * + * @return {string} Wrapped display name. + */ +// export function getWrapperDisplayName( BaseComponent, wrapperName ) { +// deprecated( 'getWrapperDisplayName', { +// version: '2.7', +// alternative: 'wp.element.createHigherOrderComponent', +// plugin: 'Gutenberg', +// } ); + +// const { displayName = BaseComponent.name || 'Component' } = BaseComponent; + +// return `${ upperFirst( camelCase( wrapperName ) ) }(${ displayName })`; +// } + +/** + * Given a function mapping a component to an enhanced component and modifier + * name, returns the enhanced component augmented with a generated displayName. + * + * @param {Function} mapComponentToEnhancedComponent Function mapping component + * to enhanced component. + * @param {string} modifierName Seed name from which to + * generated display name. + * + * @return {WPComponent} Component class with generated display name assigned. + */ +// export function createHigherOrderComponent( mapComponentToEnhancedComponent, modifierName ) { +// return ( OriginalComponent ) => { +// const EnhancedComponent = mapComponentToEnhancedComponent( OriginalComponent ); +// const { displayName = OriginalComponent.name || 'Component' } = OriginalComponent; +// EnhancedComponent.displayName = `${ upperFirst( camelCase( modifierName ) ) }(${ displayName })`; + +// return EnhancedComponent; +// }; +// } + +/** + * Component used as equivalent of Fragment with unescaped HTML, in cases where + * it is desirable to render dangerous HTML without needing a wrapper element. + * To preserve additional props, a `div` wrapper _will_ be created if any props + * aside from `children` are passed. + * + * @param {string} props.children HTML to render. + * + * @return {WPElement} Dangerously-rendering element. + */ +export function RawHTML( { children, ...props } ) { + // Render wrapper only if props are non-empty. + const tagName = isEmpty( props ) ? 'wp-raw-html' : 'div'; + + // Merge HTML into assigned props. + props = { + dangerouslySetInnerHTML: { __html: children }, + ...props, + }; + + return createElement( tagName, props ); +} diff --git a/utils/index.native.js b/utils/index.native.js new file mode 100644 index 0000000000000..d8998e9dc0da1 --- /dev/null +++ b/utils/index.native.js @@ -0,0 +1,16 @@ +// import * as focus from './focus'; +import * as keycodes from './keycodes'; +import * as viewPort from './viewport'; +import { decodeEntities } from './entities'; + +// export { focus }; +export { keycodes }; +export { decodeEntities }; + +export * from './blob-cache'; +// export * from './dom'; +export * from './mediaupload'; +export * from './terms'; +export * from './deprecation'; + +export { viewPort }; From 9b5a3f8b75ee66e881579ae14b154c8dabe3ff50 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Thu, 5 Apr 2018 03:04:10 +0300 Subject: [PATCH 19/38] RN app tests need createElement exported --- element/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/element/index.native.js b/element/index.native.js index d4ecb8de5aa97..43e3e8890964e 100644 --- a/element/index.native.js +++ b/element/index.native.js @@ -40,7 +40,7 @@ import serialize from './serialize'; * * @return {WPElement} Element. */ -// export { createElement }; +export { createElement }; /** * Renders a given element into the target DOM node. From a2a1a04e9803137eef5bc9d704e12fa5b37164b6 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Tue, 10 Apr 2018 19:48:08 +0300 Subject: [PATCH 20/38] Export serialize from serializer --- blocks/api/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/api/index.native.js b/blocks/api/index.native.js index 24febf805478a..6f7e8e6a45a23 100644 --- a/blocks/api/index.native.js +++ b/blocks/api/index.native.js @@ -8,7 +8,7 @@ export { createBlock } from // getPossibleBlockTransformations, // export { default as parse, getBlockAttributes } from './parser'; // export { default as rawHandler } from './raw-handling'; export { -// default as serialize, + default as serialize, getBlockContent, // getBlockDefaultClassname, // getSaveElement, From 95b17a2a903b8ee01e9baf5c20a8fea2f95101f2 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Thu, 12 Apr 2018 17:21:05 +0300 Subject: [PATCH 21/38] Load native version of plain-text's CSS module --- blocks/plain-text/index.native.js | 4 ++-- blocks/plain-text/style.native.scss | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 blocks/plain-text/style.native.scss diff --git a/blocks/plain-text/index.native.js b/blocks/plain-text/index.native.js index 63a01eb2b1ef8..9d0369d05583b 100644 --- a/blocks/plain-text/index.native.js +++ b/blocks/plain-text/index.native.js @@ -2,16 +2,16 @@ * External dependencies */ import { TextInput } from 'react-native'; -import classnames from 'classnames'; /** * Internal dependencies */ +import styles from './style.scss'; function PlainText( { onChange, className, ...props } ) { return ( <TextInput - className={ classnames( 'blocks-plain-text', className ) } + className={ [ styles.blocks_plain_text, className ] } onChangeText={ ( text ) => onChange( text ) } { ...props } /> diff --git a/blocks/plain-text/style.native.scss b/blocks/plain-text/style.native.scss new file mode 100644 index 0000000000000..961a786c49231 --- /dev/null +++ b/blocks/plain-text/style.native.scss @@ -0,0 +1,16 @@ +.blocks_plain_text { + box-shadow: none; + + // 'inherit' is not supported + // font-family: inherit; + // font-size: inherit; + // color: inherit; + // line-height: inherit; + + // 'border' is not supported + // border: none; + + padding: 0; + margin: 0; + width: 100%; +} From 737a4989899471fceead2a9bef0952e196a9e163 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Thu, 12 Apr 2018 22:25:35 +0300 Subject: [PATCH 22/38] Make it clear that RN uses styles, not classnames --- blocks/library/code/edit.native.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/blocks/library/code/edit.native.js b/blocks/library/code/edit.native.js index 4d722e20e88cf..d058ae9c9b83e 100644 --- a/blocks/library/code/edit.native.js +++ b/blocks/library/code/edit.native.js @@ -12,11 +12,12 @@ import { __ } from '../../../i18n'; */ import PlainText from '../../plain-text'; -export function edit( { attributes, setAttributes, className } ) { +export function edit( { attributes, setAttributes, style } ) { return ( - <View className={ className }> + <View> <PlainText value={ attributes.content } + style={ style } multiline={ true } underlineColorAndroid="transparent" onChange={ content => setAttributes( { content } ) } From 49ceaa8c29e9087c7af33e7e3bf8d2722f543914 Mon Sep 17 00:00:00 2001 From: Maxime Biais <maxime.biais@gmail.com> Date: Tue, 17 Apr 2018 16:41:36 +0200 Subject: [PATCH 23/38] Use the i18n package from @wordpress --- blocks/api/factory.native.js | 2 +- blocks/library/code/edit.native.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/blocks/api/factory.native.js b/blocks/api/factory.native.js index febe979253bba..b63a03721e20f 100644 --- a/blocks/api/factory.native.js +++ b/blocks/api/factory.native.js @@ -20,7 +20,7 @@ import { /** * WordPress dependencies */ -import { __ } from '../../i18n'; +import { __ } from '@wordpress/i18n'; // import { applyFilters } from '@wordpress/hooks'; /** diff --git a/blocks/library/code/edit.native.js b/blocks/library/code/edit.native.js index d058ae9c9b83e..1baf286a20b06 100644 --- a/blocks/library/code/edit.native.js +++ b/blocks/library/code/edit.native.js @@ -5,7 +5,7 @@ import { View } from 'react-native'; /** * WordPress dependencies */ -import { __ } from '../../../i18n'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies From 836c51eedaede620d785b4671181f3cbf279092b Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 27 Apr 2018 16:35:57 +0300 Subject: [PATCH 24/38] Remove some commented out code --- blocks/api/factory.native.js | 94 ---------------- blocks/api/index.native.js | 33 +----- blocks/library/index.native.js | 82 -------------- element/index.native.js | 192 --------------------------------- 4 files changed, 5 insertions(+), 396 deletions(-) diff --git a/blocks/api/factory.native.js b/blocks/api/factory.native.js index b63a03721e20f..ac1f3b1eb0a0e 100644 --- a/blocks/api/factory.native.js +++ b/blocks/api/factory.native.js @@ -6,10 +6,7 @@ import { every, get, reduce, - // castArray, - // findIndex, includes, - // isObjectLike, filter, find, first, @@ -21,7 +18,6 @@ import { * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -// import { applyFilters } from '@wordpress/hooks'; /** * Internal dependencies @@ -168,96 +164,6 @@ export function getPossibleBlockTransformations( blocks ) { }, [] ); } -// /** -// * Switch one or more blocks into one or more blocks of the new block type. -// * -// * @param {Array|Object} blocks Blocks array or block object. -// * @param {string} name Block name. -// * -// * @return {Array} Array of blocks. -// */ -// export function switchToBlockType( blocks, name ) { -// const blocksArray = castArray( blocks ); -// const isMultiBlock = blocksArray.length > 1; -// const firstBlock = blocksArray[ 0 ]; -// const sourceName = firstBlock.name; - -// if ( isMultiBlock && ! every( blocksArray, ( block ) => ( block.name === sourceName ) ) ) { -// return null; -// } - -// // Find the right transformation by giving priority to the "to" -// // transformation. -// const destinationType = getBlockType( name ); -// const sourceType = getBlockType( sourceName ); -// const transformationsFrom = get( destinationType, 'transforms.from', [] ); -// const transformationsTo = get( sourceType, 'transforms.to', [] ); -// const transformation = -// find( -// transformationsTo, -// t => t.type === 'block' && t.blocks.indexOf( name ) !== -1 && ( ! isMultiBlock || t.isMultiBlock ) -// ) || -// find( -// transformationsFrom, -// t => t.type === 'block' && t.blocks.indexOf( sourceName ) !== -1 && ( ! isMultiBlock || t.isMultiBlock ) -// ); - -// // Stop if there is no valid transformation. (How did we get here?) -// if ( ! transformation ) { -// return null; -// } - -// let transformationResults; -// if ( transformation.isMultiBlock ) { -// transformationResults = transformation.transform( blocksArray.map( ( currentBlock ) => currentBlock.attributes ) ); -// } else { -// transformationResults = transformation.transform( firstBlock.attributes ); -// } - -// // Ensure that the transformation function returned an object or an array -// // of objects. -// if ( ! isObjectLike( transformationResults ) ) { -// return null; -// } - -// // If the transformation function returned a single object, we want to work -// // with an array instead. -// transformationResults = castArray( transformationResults ); - -// // Ensure that every block object returned by the transformation has a -// // valid block type. -// if ( transformationResults.some( ( result ) => ! getBlockType( result.name ) ) ) { -// return null; -// } - -// const firstSwitchedBlock = findIndex( transformationResults, ( result ) => result.name === name ); - -// // Ensure that at least one block object returned by the transformation has -// // the expected "destination" block type. -// if ( firstSwitchedBlock < 0 ) { -// return null; -// } - -// return transformationResults.map( ( result, index ) => { -// const transformedBlock = { -// ...result, -// // The first transformed block whose type matches the "destination" -// // type gets to keep the existing UID of the first block. -// uid: index === firstSwitchedBlock ? firstBlock.uid : result.uid, -// }; - -// /** -// * Filters an individual transform result from block transformation. -// * All of the original blocks are passed, since transformations are -// * many-to-many, not one-to-one. -// * -// * @param {Object} transformedBlock The transformed block. -// * @param {Object[]} blocks Original blocks transformed. -// */ -// return applyFilters( 'blocks.switchToBlockType.transformedBlock', transformedBlock, blocks ); -// } ); -// } - /** * Creates a new reusable block. * diff --git a/blocks/api/index.native.js b/blocks/api/index.native.js index 6f7e8e6a45a23..e657117820229 100644 --- a/blocks/api/index.native.js +++ b/blocks/api/index.native.js @@ -1,36 +1,13 @@ /** @format */ -// cloneBlock, -export { createBlock } from // getPossibleBlockTransformations, -// switchToBlockType, -// createReusableBlock, - './factory'; -// export { default as parse, getBlockAttributes } from './parser'; -// export { default as rawHandler } from './raw-handling'; +export { + createBlock, +} from './factory'; export { default as serialize, getBlockContent, -// getBlockDefaultClassname, -// getSaveElement, -} from - './serializer'; -// export { isValidBlock } from './validation'; -// export { getCategories } from './categories'; -// getBlockTypes, +} from './serializer'; export { registerBlockType, - // unregisterBlockType, - // setUnknownTypeHandlerName, - // getUnknownTypeHandlerName, - // setDefaultBlockName, - // getDefaultBlockName, - // getDefaultBlockForPostFormat, getBlockType, - // getBlockSupport, - // hasBlockSupport, - // isReusableBlock, -} from - './registration'; -// export { -// isUnmodifiedDefaultBlock, -// } from './utils'; +} from './registration'; diff --git a/blocks/library/index.native.js b/blocks/library/index.native.js index 71b6b8eff9c15..4e37e2a36d9c9 100644 --- a/blocks/library/index.native.js +++ b/blocks/library/index.native.js @@ -5,95 +5,13 @@ */ import { registerBlockType, - // setDefaultBlockName, - // setUnknownTypeHandlerName, } from '../api'; -// import * as paragraph from './paragraph'; -// import * as image from './image'; -// import * as heading from './heading'; -// import * as quote from './quote'; -// import * as gallery from './gallery'; -// import * as audio from './audio'; -// import * as button from './button'; -// import * as categories from './categories'; import * as code from './code'; -// import * as columns from './columns'; -// import * as coverImage from './cover-image'; -// import * as embed from './embed'; -// import * as freeform from './freeform'; -// import * as html from './html'; -// import * as latestPosts from './latest-posts'; -// import * as list from './list'; -// import * as more from './more'; -// import * as preformatted from './preformatted'; -// import * as pullquote from './pullquote'; -// import * as reusableBlock from './block'; -// import * as separator from './separator'; -// import * as shortcode from './shortcode'; -// import * as subhead from './subhead'; -// import * as table from './table'; -// import * as textColumns from './text-columns'; -// import * as verse from './verse'; -// import * as video from './video'; export const registerCoreBlocks = () => { [ - // // FIXME: Temporary fix. - // // - // // The Shortcode block declares a catch-all shortcode transform, - // // meaning it will attempt to intercept pastes and block conversions of - // // any valid shortcode-like content. Other blocks (e.g. Gallery) may - // // declare specific shortcode transforms (e.g. `[gallery]`), with which - // // this block would conflict. Thus, the Shortcode block needs to be - // // registered as early as possible, so that any other block types' - // // shortcode transforms can be honoured. - // // - // // This isn't a proper solution, as it is at odds with the - // // specification of shortcode conversion, in the sense that conversion - // // is explicitly independent of block order. Thus, concurrent parse - // // rules (i.e. a same text input can yield two different transforms, - // // like `[gallery] -> { Gallery, Shortcode }`) are unsupported, - // // yielding non-deterministic results. A proper solution could be to - // // let the editor (or site owners) determine a default block handler of - // // unknown shortcodes — see `setUnknownTypeHandlerName`. - // shortcode, - - // // Common blocks are grouped at the top to prioritize their display - // // in various contexts — like the inserter and auto-complete components. - // paragraph, - // image, - // heading, - // gallery, - // list, - // quote, - - // // Register all remaining core blocks. - // audio, - // button, - // categories, code, - // columns, - // coverImage, - // embed, - // ...embed.common, - // ...embed.others, - // freeform, - // html, - // latestPosts, - // more, - // preformatted, - // pullquote, - // reusableBlock, - // separator, - // subhead, - // table, - // textColumns, - // verse, - // video, ].forEach( ( { name, settings } ) => { registerBlockType( name, settings ); } ); - - // setDefaultBlockName( paragraph.name ); - // setUnknownTypeHandlerName( freeform.name ); }; diff --git a/element/index.native.js b/element/index.native.js index 43e3e8890964e..2976db326fbfd 100644 --- a/element/index.native.js +++ b/element/index.native.js @@ -2,26 +2,9 @@ * External dependencies */ import { - // createContext, createElement, Component, - // cloneElement, - // Children, - // Fragment } from 'react'; -// import { render, findDOMNode, createPortal, unmountComponentAtNode } from 'react-dom'; -import { - // camelCase, - // flowRight, - // isString, - // upperFirst, - isEmpty, -} from 'lodash'; - -/** - * WordPress dependencies - */ -// import { deprecated } from '@wordpress/utils'; /** * Internal dependencies @@ -42,70 +25,11 @@ import serialize from './serialize'; */ export { createElement }; -/** - * Renders a given element into the target DOM node. - * - * @param {WPElement} element Element to render - * @param {Element} target DOM node into which element should be rendered - */ -// export { render }; - -/** - * Removes any mounted element from the target DOM node. - * - * @param {Element} target DOM node in which element is to be removed - */ -// export { unmountComponentAtNode }; - /** * A base class to create WordPress Components (Refs, state and lifecycle hooks) */ export { Component }; -/** - * Creates a copy of an element with extended props. - * - * @param {WPElement} element Element - * @param {?Object} props Props to apply to cloned element - * - * @return {WPElement} Cloned element. - */ -// export { cloneElement }; - -/** - * Finds the dom node of a React component - * - * @param {Component} component component's instance - * @param {Element} target DOM node into which element should be rendered - */ -// export { findDOMNode }; - -// export { Children }; - -/** - * A component which renders its children without any wrapping element. - */ -// export { Fragment }; - -/** - * Creates a context object containing two components: a provider and consumer. - * - * @param {Object} defaultValue Data stored in the context. - * - * @return {Object} Context object. - */ -// export { createContext }; - -/** - * Creates a portal into which a component can be rendered. - * - * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235 - * - * @param {Component} component Component - * @param {Element} target DOM node into which element should be rendered - */ -// export { createPortal }; - /** * Renders a given element into a string. * @@ -114,119 +38,3 @@ export { Component }; * @return {string} HTML. */ export { serialize as renderToString }; - -/** - * Concatenate two or more React children objects. - * - * @param {...?Object} childrenArguments Array of children arguments (array of arrays/strings/objects) to concatenate. - * - * @return {Array} The concatenated value. - */ -// export function concatChildren( ...childrenArguments ) { -// return childrenArguments.reduce( ( memo, children, i ) => { -// Children.forEach( children, ( child, j ) => { -// if ( child && 'string' !== typeof child ) { -// child = cloneElement( child, { -// key: [ i, j ].join(), -// } ); -// } - -// memo.push( child ); -// } ); - -// return memo; -// }, [] ); -// } - -/** - * Switches the nodeName of all the elements in the children object. - * - * @param {?Object} children Children object. - * @param {string} nodeName Node name. - * - * @return {?Object} The updated children object. - */ -// export function switchChildrenNodeName( children, nodeName ) { -// return children && Children.map( children, ( elt, index ) => { -// if ( isString( elt ) ) { -// return createElement( nodeName, { key: index }, elt ); -// } -// const { children: childrenProp, ...props } = elt.props; -// return createElement( nodeName, { key: index, ...props }, childrenProp ); -// } ); -// } - -/** - * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function - * composition, where each successive invocation is supplied the return value of the previous. - * - * @param {...Function} hocs The HOC functions to invoke. - * - * @return {Function} Returns the new composite function. - */ -// export { flowRight as compose }; - -/** - * Returns a wrapped version of a React component's display name. - * Higher-order components use getWrapperDisplayName(). - * - * @param {Function|Component} BaseComponent Used to detect the existing display name. - * @param {string} wrapperName Wrapper name to prepend to the display name. - * - * @return {string} Wrapped display name. - */ -// export function getWrapperDisplayName( BaseComponent, wrapperName ) { -// deprecated( 'getWrapperDisplayName', { -// version: '2.7', -// alternative: 'wp.element.createHigherOrderComponent', -// plugin: 'Gutenberg', -// } ); - -// const { displayName = BaseComponent.name || 'Component' } = BaseComponent; - -// return `${ upperFirst( camelCase( wrapperName ) ) }(${ displayName })`; -// } - -/** - * Given a function mapping a component to an enhanced component and modifier - * name, returns the enhanced component augmented with a generated displayName. - * - * @param {Function} mapComponentToEnhancedComponent Function mapping component - * to enhanced component. - * @param {string} modifierName Seed name from which to - * generated display name. - * - * @return {WPComponent} Component class with generated display name assigned. - */ -// export function createHigherOrderComponent( mapComponentToEnhancedComponent, modifierName ) { -// return ( OriginalComponent ) => { -// const EnhancedComponent = mapComponentToEnhancedComponent( OriginalComponent ); -// const { displayName = OriginalComponent.name || 'Component' } = OriginalComponent; -// EnhancedComponent.displayName = `${ upperFirst( camelCase( modifierName ) ) }(${ displayName })`; - -// return EnhancedComponent; -// }; -// } - -/** - * Component used as equivalent of Fragment with unescaped HTML, in cases where - * it is desirable to render dangerous HTML without needing a wrapper element. - * To preserve additional props, a `div` wrapper _will_ be created if any props - * aside from `children` are passed. - * - * @param {string} props.children HTML to render. - * - * @return {WPElement} Dangerously-rendering element. - */ -export function RawHTML( { children, ...props } ) { - // Render wrapper only if props are non-empty. - const tagName = isEmpty( props ) ? 'wp-raw-html' : 'div'; - - // Merge HTML into assigned props. - props = { - dangerouslySetInnerHTML: { __html: children }, - ...props, - }; - - return createElement( tagName, props ); -} From ce3c5c454edc4f42b0eb21425fd20138b1a1b08a Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 27 Apr 2018 16:36:06 +0300 Subject: [PATCH 25/38] Utils are not currently used on native --- utils/index.native.js | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 utils/index.native.js diff --git a/utils/index.native.js b/utils/index.native.js deleted file mode 100644 index d8998e9dc0da1..0000000000000 --- a/utils/index.native.js +++ /dev/null @@ -1,16 +0,0 @@ -// import * as focus from './focus'; -import * as keycodes from './keycodes'; -import * as viewPort from './viewport'; -import { decodeEntities } from './entities'; - -// export { focus }; -export { keycodes }; -export { decodeEntities }; - -export * from './blob-cache'; -// export * from './dom'; -export * from './mediaupload'; -export * from './terms'; -export * from './deprecation'; - -export { viewPort }; From 33f9764bd878525016f4be005403deb1d2069e9c Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 27 Apr 2018 16:42:27 +0300 Subject: [PATCH 26/38] 'Border' property not supported in shorthand form --- blocks/plain-text/style.native.scss | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/blocks/plain-text/style.native.scss b/blocks/plain-text/style.native.scss index 961a786c49231..ee956cee6bf5a 100644 --- a/blocks/plain-text/style.native.scss +++ b/blocks/plain-text/style.native.scss @@ -1,14 +1,7 @@ .blocks_plain_text { box-shadow: none; - // 'inherit' is not supported - // font-family: inherit; - // font-size: inherit; - // color: inherit; - // line-height: inherit; - - // 'border' is not supported - // border: none; + border-width: 0; padding: 0; margin: 0; From 2bbcbc8fb3161699489926b97e0ea1845340693e Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 27 Apr 2018 16:45:15 +0300 Subject: [PATCH 27/38] Use hypens in css class names as traditionally --- blocks/plain-text/index.native.js | 2 +- blocks/plain-text/style.native.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/blocks/plain-text/index.native.js b/blocks/plain-text/index.native.js index 9d0369d05583b..78f60593a6bfc 100644 --- a/blocks/plain-text/index.native.js +++ b/blocks/plain-text/index.native.js @@ -11,7 +11,7 @@ import styles from './style.scss'; function PlainText( { onChange, className, ...props } ) { return ( <TextInput - className={ [ styles.blocks_plain_text, className ] } + className={ [ styles[ 'blocks-plain-text' ], className ] } onChangeText={ ( text ) => onChange( text ) } { ...props } /> diff --git a/blocks/plain-text/style.native.scss b/blocks/plain-text/style.native.scss index ee956cee6bf5a..c1b9d5fe674d9 100644 --- a/blocks/plain-text/style.native.scss +++ b/blocks/plain-text/style.native.scss @@ -1,4 +1,4 @@ -.blocks_plain_text { +.blocks-plain-text { box-shadow: none; border-width: 0; From 837f029398cc7c6221431bfd8ef6b147f30e96f5 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 27 Apr 2018 17:02:47 +0300 Subject: [PATCH 28/38] remove unused code --- blocks/api/factory.native.js | 138 +---------------------------------- 1 file changed, 1 insertion(+), 137 deletions(-) diff --git a/blocks/api/factory.native.js b/blocks/api/factory.native.js index ac1f3b1eb0a0e..ba2a5f5aee60c 100644 --- a/blocks/api/factory.native.js +++ b/blocks/api/factory.native.js @@ -3,26 +3,13 @@ */ import uuid from 'uuid/v4'; import { - every, - get, reduce, - includes, - filter, - find, - first, - flatMap, - uniqueId, } from 'lodash'; -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - /** * Internal dependencies */ -import { getBlockType, getBlockTypes } from './registration'; +import { getBlockType } from './registration'; /** * Returns a block object given its type and attributes. @@ -60,126 +47,3 @@ export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { innerBlocks, }; } - -/** - * Given a block object, returns a copy of the block object, optionally merging - * new attributes and/or replacing its inner blocks. - * - * @param {Object} block Block object. - * @param {Object} mergeAttributes Block attributes. - * @param {?Array} innerBlocks Nested blocks. - * - * @return {Object} A cloned block. - */ -export function cloneBlock( block, mergeAttributes = {}, innerBlocks = block.innerBlocks ) { - return { - ...block, - uid: uuid(), - attributes: { - ...block.attributes, - ...mergeAttributes, - }, - innerBlocks, - }; -} - -/** - * Returns a predicate that receives a transformation and returns true if the - * given transformation is able to execute in the situation specified in the - * params. - * - * @param {string} sourceName Block name. - * @param {boolean} isMultiBlock Array of possible block transformations. - * - * @return {Function} Predicate that receives a block type. - */ -const isTransformForBlockSource = ( sourceName, isMultiBlock = false ) => ( transform ) => ( - transform.type === 'block' && - transform.blocks.indexOf( sourceName ) !== -1 && - ( ! isMultiBlock || transform.isMultiBlock ) -); - -/** - * Returns a predicate that receives a block type and returns true if the given - * block type contains a transformation able to execute in the situation - * specified in the params. - * - * @param {string} sourceName Block name. - * @param {boolean} isMultiBlock Array of possible block transformations. - * - * @return {Function} Predicate that receives a block type. - */ -const createIsTypeTransformableFrom = ( sourceName, isMultiBlock = false ) => ( type ) => ( - !! find( - get( type, 'transforms.from', [] ), - isTransformForBlockSource( sourceName, isMultiBlock ), - ) -); - -/** - * Returns an array of possible block transformations that could happen on the - * set of blocks received as argument. - * - * @param {Array} blocks Blocks array. - * - * @return {Array} Array of possible block transformations. - */ -export function getPossibleBlockTransformations( blocks ) { - const sourceBlock = first( blocks ); - if ( ! blocks || ! sourceBlock ) { - return []; - } - const isMultiBlock = blocks.length > 1; - const sourceBlockName = sourceBlock.name; - - if ( isMultiBlock && ! every( blocks, { name: sourceBlockName } ) ) { - return []; - } - - // Compute the block that have a from transformation able to transfer blocks passed as argument. - const blocksToBeTransformedFrom = filter( - getBlockTypes(), - createIsTypeTransformableFrom( sourceBlockName, isMultiBlock ), - ).map( type => type.name ); - - const blockType = getBlockType( sourceBlockName ); - const transformsTo = get( blockType, 'transforms.to', [] ); - - // Generate list of block transformations using the supplied "transforms to". - const blocksToBeTransformedTo = flatMap( - isMultiBlock ? filter( transformsTo, 'isMultiBlock' ) : transformsTo, - transformation => transformation.blocks - ); - - // Returns a unique list of available block transformations. - return reduce( [ - ...blocksToBeTransformedFrom, - ...blocksToBeTransformedTo, - ], ( result, name ) => { - const transformBlockType = getBlockType( name ); - if ( transformBlockType && ! includes( result, transformBlockType ) ) { - result.push( transformBlockType ); - } - return result; - }, [] ); -} - -/** - * Creates a new reusable block. - * - * @param {string} type The type of the block referenced by the reusable - * block. - * @param {Object} attributes The attributes of the block referenced by the - * reusable block. - * - * @return {Object} A reusable block object. - */ -export function createReusableBlock( type, attributes ) { - return { - id: -uniqueId(), // Temporary id replaced when the block is saved server side - isTemporary: true, - title: __( 'Untitled block' ), - type, - attributes, - }; -} From 2a982324c59eecbdb47331b75cc3414e8671a1cb Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 27 Apr 2018 17:45:40 +0300 Subject: [PATCH 29/38] No need for platform-specific factory.js --- blocks/api/factory.native.js | 49 ------------------------------------ 1 file changed, 49 deletions(-) delete mode 100644 blocks/api/factory.native.js diff --git a/blocks/api/factory.native.js b/blocks/api/factory.native.js deleted file mode 100644 index ba2a5f5aee60c..0000000000000 --- a/blocks/api/factory.native.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * External dependencies - */ -import uuid from 'uuid/v4'; -import { - reduce, -} from 'lodash'; - -/** - * Internal dependencies - */ -import { getBlockType } from './registration'; - -/** - * Returns a block object given its type and attributes. - * - * @param {string} name Block name. - * @param {Object} blockAttributes Block attributes. - * @param {?Array} innerBlocks Nested blocks. - * - * @return {Object} Block object. - */ -export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { - // Get the type definition associated with a registered block. - const blockType = getBlockType( name ); - - // Ensure attributes contains only values defined by block type, and merge - // default values for missing attributes. - const attributes = reduce( blockType.attributes, ( result, source, key ) => { - const value = blockAttributes[ key ]; - if ( undefined !== value ) { - result[ key ] = value; - } else if ( source.hasOwnProperty( 'default' ) ) { - result[ key ] = source.default; - } - - return result; - }, {} ); - - // Blocks are stored with a unique ID, the assigned type name, - // the block attributes, and their inner blocks. - return { - uid: uuid(), - name, - isValid: true, - attributes, - innerBlocks, - }; -} From eed0531453589214b83ed1ea62e20e3604eddbf1 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 30 Apr 2018 10:14:26 +0300 Subject: [PATCH 30/38] Move native files after update from master --- blocks/index.native.js | 12 ++++++++++++ {blocks/library => core-blocks}/code/edit.js | 4 ++-- {blocks/library => core-blocks}/code/edit.native.js | 4 ++-- {blocks/library => core-blocks}/index.native.js | 10 ++++++---- 4 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 blocks/index.native.js rename {blocks/library => core-blocks}/code/edit.js (90%) rename {blocks/library => core-blocks}/code/edit.native.js (82%) rename {blocks/library => core-blocks}/index.native.js (78%) diff --git a/blocks/index.native.js b/blocks/index.native.js new file mode 100644 index 0000000000000..c949cf17d0a2a --- /dev/null +++ b/blocks/index.native.js @@ -0,0 +1,12 @@ +// A "block" is the abstract term used to describe units of markup that, +// when composed together, form the content or layout of a page. +// The API for blocks is exposed via `wp.blocks`. +// +// Supported blocks are registered by calling `registerBlockType`. Once registered, +// the block is made available as an option to the editor interface. +// +// Blocks are inferred from the HTML source of a post through a parsing mechanism +// and then stored as objects in state, from which it is then rendered for editing. +export * from './api'; + +export { default as PlainText } from './plain-text'; diff --git a/blocks/library/code/edit.js b/core-blocks/code/edit.js similarity index 90% rename from blocks/library/code/edit.js rename to core-blocks/code/edit.js index b5b38ac74487a..8fa69acb71848 100644 --- a/blocks/library/code/edit.js +++ b/core-blocks/code/edit.js @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import './editor.scss'; -import PlainText from '../../plain-text'; +import { PlainText } from '@wordpress/blocks'; export function edit( { attributes, setAttributes, className } ) { return ( @@ -20,4 +20,4 @@ export function edit( { attributes, setAttributes, className } ) { /> </div> ); -} +} \ No newline at end of file diff --git a/blocks/library/code/edit.native.js b/core-blocks/code/edit.native.js similarity index 82% rename from blocks/library/code/edit.native.js rename to core-blocks/code/edit.native.js index 1baf286a20b06..4b5aa5c1989a5 100644 --- a/blocks/library/code/edit.native.js +++ b/core-blocks/code/edit.native.js @@ -10,7 +10,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import PlainText from '../../plain-text'; +import { PlainText } from '../../blocks'; export function edit( { attributes, setAttributes, style } ) { return ( @@ -20,7 +20,7 @@ export function edit( { attributes, setAttributes, style } ) { style={ style } multiline={ true } underlineColorAndroid="transparent" - onChange={ content => setAttributes( { content } ) } + onChange={ ( content ) => setAttributes( { content } ) } placeholder={ __( 'Write code…' ) } aria-label={ __( 'Code' ) } /> diff --git a/blocks/library/index.native.js b/core-blocks/index.native.js similarity index 78% rename from blocks/library/index.native.js rename to core-blocks/index.native.js index 4e37e2a36d9c9..44a282e6a1eae 100644 --- a/blocks/library/index.native.js +++ b/core-blocks/index.native.js @@ -1,11 +1,13 @@ /** - * Internal dependencies - * - * @format + * WordPress dependencies */ import { registerBlockType, -} from '../api'; +} from '@wordpress/blocks'; + +/** + * Internal dependencies + */ import * as code from './code'; export const registerCoreBlocks = () => { From 779c342c51df8bb959a983bfb157881b0dd11730 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 30 Apr 2018 10:26:54 +0300 Subject: [PATCH 31/38] Codestyle fix --- core-blocks/code/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-blocks/code/edit.js b/core-blocks/code/edit.js index 8fa69acb71848..532173fe8d7c3 100644 --- a/core-blocks/code/edit.js +++ b/core-blocks/code/edit.js @@ -20,4 +20,4 @@ export function edit( { attributes, setAttributes, className } ) { /> </div> ); -} \ No newline at end of file +} From 2a97aedd4a8681c1cbc949ff788d294ed43b464f Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 30 Apr 2018 10:39:41 +0300 Subject: [PATCH 32/38] GB isn't using Prettier so, no need for the pragma --- blocks/api/index.native.js | 2 -- core-blocks/code/edit.native.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/blocks/api/index.native.js b/blocks/api/index.native.js index e657117820229..3bef99c41e803 100644 --- a/blocks/api/index.native.js +++ b/blocks/api/index.native.js @@ -1,5 +1,3 @@ -/** @format */ - export { createBlock, } from './factory'; diff --git a/core-blocks/code/edit.native.js b/core-blocks/code/edit.native.js index 4b5aa5c1989a5..0f141f96623e3 100644 --- a/core-blocks/code/edit.native.js +++ b/core-blocks/code/edit.native.js @@ -1,5 +1,3 @@ -/** @format */ - import { View } from 'react-native'; /** From 489ae72df30d4276d12c23e754c14a790544dd64 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 30 Apr 2018 10:44:29 +0300 Subject: [PATCH 33/38] Comment on the need to import the `edit` function --- core-blocks/code/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-blocks/code/index.js b/core-blocks/code/index.js index b3a9fac868ae8..0a93466dc434b 100644 --- a/core-blocks/code/index.js +++ b/core-blocks/code/index.js @@ -9,7 +9,7 @@ import { /** * Internal dependencies */ -import { edit } from './edit'; +import { edit } from './edit'; // import the specialized `edit` function. Is is different between the web and native mobile. export const name = 'core/code'; From 0edfb18e33b66c100c0fefd9e5a0e66f39e1d621 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 30 Apr 2018 11:58:10 +0300 Subject: [PATCH 34/38] Export the edit function as default --- core-blocks/code/edit.js | 2 +- core-blocks/code/edit.native.js | 2 +- core-blocks/code/index.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core-blocks/code/edit.js b/core-blocks/code/edit.js index 532173fe8d7c3..71414afaa6c00 100644 --- a/core-blocks/code/edit.js +++ b/core-blocks/code/edit.js @@ -9,7 +9,7 @@ import { __ } from '@wordpress/i18n'; import './editor.scss'; import { PlainText } from '@wordpress/blocks'; -export function edit( { attributes, setAttributes, className } ) { +export default function edit( { attributes, setAttributes, className } ) { return ( <div className={ className }> <PlainText diff --git a/core-blocks/code/edit.native.js b/core-blocks/code/edit.native.js index 0f141f96623e3..9c2f66c5aad06 100644 --- a/core-blocks/code/edit.native.js +++ b/core-blocks/code/edit.native.js @@ -10,7 +10,7 @@ import { __ } from '@wordpress/i18n'; */ import { PlainText } from '../../blocks'; -export function edit( { attributes, setAttributes, style } ) { +export default function edit( { attributes, setAttributes, style } ) { return ( <View> <PlainText diff --git a/core-blocks/code/index.js b/core-blocks/code/index.js index 0a93466dc434b..6c15108e95236 100644 --- a/core-blocks/code/index.js +++ b/core-blocks/code/index.js @@ -9,7 +9,7 @@ import { /** * Internal dependencies */ -import { edit } from './edit'; // import the specialized `edit` function. Is is different between the web and native mobile. +import edit from './edit'; // import the specialized `edit` function. Is is different between the web and native mobile. export const name = 'core/code'; From 9b68ba3a95402c23bf49b53d075a797861d9f84e Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 30 Apr 2018 11:58:44 +0300 Subject: [PATCH 35/38] Remove reduntant line comment --- core-blocks/code/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-blocks/code/index.js b/core-blocks/code/index.js index 6c15108e95236..c3a341ff6acf3 100644 --- a/core-blocks/code/index.js +++ b/core-blocks/code/index.js @@ -9,7 +9,7 @@ import { /** * Internal dependencies */ -import edit from './edit'; // import the specialized `edit` function. Is is different between the web and native mobile. +import edit from './edit'; export const name = 'core/code'; From 5c93331246e0d4a64a2ea0873ca263fac8e0fec4 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 30 Apr 2018 12:08:16 +0300 Subject: [PATCH 36/38] Import block using the new pattern --- core-blocks/code/edit.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-blocks/code/edit.native.js b/core-blocks/code/edit.native.js index 9c2f66c5aad06..5acc31d8f0b9a 100644 --- a/core-blocks/code/edit.native.js +++ b/core-blocks/code/edit.native.js @@ -8,7 +8,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { PlainText } from '../../blocks'; +import { PlainText } from '@wordpress/blocks'; export default function edit( { attributes, setAttributes, style } ) { return ( From 0377c731c98759c2724d02a60dde97d3c7e05e64 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 30 Apr 2018 13:11:55 +0300 Subject: [PATCH 37/38] Add a comment about styling --- core-blocks/code/edit.native.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core-blocks/code/edit.native.js b/core-blocks/code/edit.native.js index 5acc31d8f0b9a..bde686ed7f700 100644 --- a/core-blocks/code/edit.native.js +++ b/core-blocks/code/edit.native.js @@ -10,6 +10,8 @@ import { __ } from '@wordpress/i18n'; */ import { PlainText } from '@wordpress/blocks'; +// Note: styling is applied directly to the (nested) PlainText component. Web-side components +// apply it to the container 'div' but we don't have a proper proposal for cascading styling yet. export default function edit( { attributes, setAttributes, style } ) { return ( <View> From dfb1a12a4e39d172efcf28138b09b2ffe5055c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Fri, 4 May 2018 08:53:07 +0200 Subject: [PATCH 38/38] Use object property shorthand for `edit` --- core-blocks/code/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-blocks/code/index.js b/core-blocks/code/index.js index c3a341ff6acf3..125909bab1924 100644 --- a/core-blocks/code/index.js +++ b/core-blocks/code/index.js @@ -54,7 +54,7 @@ export const settings = { ], }, - edit: edit, + edit, save( { attributes } ) { return <pre><code>{ attributes.content }</code></pre>;