Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Enhance the shortcode block to support previewing of shortcodes #4710

Closed
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c3fd280
Work in progress fixes for ticket #1054
Jan 24, 2018
8cec7fc
eslint fixes and reordering for better readibility and conforming to …
Jan 25, 2018
9fc96f8
Minor changes to the title and code comments to change language to sh…
Jan 25, 2018
00abaca
Post ID is now retrieved from redux store, instead of from GET params
Jan 25, 2018
3646f61
Injects custom css and js that might be needed by iframe
Jan 27, 2018
2681b28
Checks shortcode content type and fetches custom css/js (if any)
Jan 27, 2018
d7971cb
JS and CSS fixes to enable rendering of shortcode previews
Jan 27, 2018
3e5c6b4
Merge remote-tracking branch 'upstream/master'
Jan 27, 2018
80800ed
fixes warnings
Jan 27, 2018
63549b4
fixes warnings
Jan 27, 2018
9997daf
fixes warnings
Jan 27, 2018
4095bca
fixes warnings
Jan 27, 2018
aa57071
fixes warnings
Jan 27, 2018
0e71158
Bug fix : [playlist] shortcode now renders in the preview
Jan 28, 2018
4871b73
Fixes jest Snapshot which caused the tests to fail
Jan 30, 2018
7f00de6
Merge remote-tracking branch 'upstream/master'
Feb 2, 2018
a6d250a
Enhancement: Implements caching of results
niranjan-uma-shankar Feb 2, 2018
3a55c5a
lint fixes
niranjan-uma-shankar Feb 2, 2018
7fdad34
Fix: Don't save in transients if result is empty
niranjan-uma-shankar Feb 2, 2018
a486b44
Fix: Handles better empty shortcode output scenario
niranjan-uma-shankar Feb 2, 2018
c9f11b5
Minor fix: Translatable function for a string was missing, fixed it
niranjan-uma-shankar Feb 3, 2018
5bf4ea3
Added some null checks
niranjan-uma-shankar Feb 3, 2018
861dd1c
Unit tests for the Shortcode preview rendering REST API.
niranjan-uma-shankar Feb 3, 2018
bc9a96a
Added some error messages
niranjan-uma-shankar Feb 6, 2018
fc05936
Refactored code & breaking down to components
niranjan-uma-shankar Feb 6, 2018
d2143a5
Updated tests to reflect new refactor changes
niranjan-uma-shankar Feb 6, 2018
6c31a5f
Code refactor
niranjan-uma-shankar Feb 6, 2018
f6d525f
Adding a comment
niranjan-uma-shankar Feb 6, 2018
6aacd6e
Added encodeURIcomponent() to encode the shortcode content on the fro…
niranjan-uma-shankar Feb 12, 2018
54f2fb3
Refactored code
niranjan-uma-shankar Feb 15, 2018
e4bbdb6
Removed these lines - they were added as a fix for an earlier observe…
niranjan-uma-shankar Feb 15, 2018
63cfafd
Merge remote-tracking branch 'upstream/master'
niranjan-uma-shankar Feb 15, 2018
2ce2fef
Drop the focus/setFocus props from block edit functions (#4872)
niranjan-uma-shankar Feb 15, 2018
3797ce8
Drop the focus/setFocus props from block edit functions (#4872)
niranjan-uma-shankar Feb 15, 2018
65efa0b
[embed] shortcode previews are rendered with oembed endpoint
niranjan-uma-shankar Feb 17, 2018
1259bc9
Moved connect HOC to ShortcodePreview component, so that jest tests c…
niranjan-uma-shankar Feb 19, 2018
3b506ed
Avoiding the selector, since it creates an issue with bundle size due…
niranjan-uma-shankar Feb 24, 2018
9230d75
rebase master
niranjan-uma-shankar Feb 24, 2018
f837d0a
Variable name changes
niranjan-uma-shankar Feb 25, 2018
8237a66
Refactoring changes
niranjan-uma-shankar Feb 25, 2018
0ae8100
Modifications to the tests in line with the REST API changes
niranjan-uma-shankar Feb 25, 2018
d8ed5b2
Merge remote-tracking branch 'upstream/master'
niranjan-uma-shankar Feb 25, 2018
49b2e85
Undo logging changes
niranjan-uma-shankar Feb 25, 2018
4595fb4
Updated schema, and fixed lint
niranjan-uma-shankar Feb 26, 2018
777b304
Reverting API changes to do_shortcode/run_shortcode method
niranjan-uma-shankar Mar 6, 2018
80ae62a
Merge
niranjan-uma-shankar Apr 15, 2018
d81a308
Merge
niranjan-uma-shankar Apr 15, 2018
12d83a0
Merge remote-tracking branch 'upstream/master'
niranjan-uma-shankar Apr 15, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ Please see <a href="https://github.com/WordPress/gutenberg/blob/master/CONTRIBUT
- <a href="https://make.wordpress.org/core/tag/gutenberg/">Development updates on make.wordpress.org</a>
- <a href="https://wordpress.org/gutenberg/handbook/">Documentation: Creating Blocks, Reference, and Guidelines</a>

<br/><br/>![Code is Poetry.](https://cldup.com/ZdtsUVg_V3.png)
<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>
2 changes: 2 additions & 0 deletions blocks/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ export {
getUnknownTypeHandlerName,
setDefaultBlockName,
getDefaultBlockName,
getDefaultBlockForPostFormat,
getBlockType,
getBlockTypes,
getBlockSupport,
hasBlockSupport,
isReusableBlock,
} from './registration';
Expand Down
26 changes: 1 addition & 25 deletions blocks/api/post.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -169,33 +169,9 @@ Block_List
}

Token
= Tag_More
/ Block_Void
= Block_Void
/ Block_Balanced

Tag_More
= "<!--" WS* "more" customText:(WS+ text:$((!(WS* "-->") .)+) { /** <?php return $text; ?> **/ return text })? WS* "-->" noTeaser:(WS* "<!--noteaser-->")?
{ /** <?php
$attrs = array( 'noTeaser' => (bool) $noTeaser );
if ( ! empty( $customText ) ) {
$attrs['customText'] = $customText;
}
return array(
'blockName' => 'core/more',
'attrs' => $attrs,
'innerHTML' => ''
);
?> **/
return {
blockName: 'core/more',
attrs: {
customText: customText || undefined,
noTeaser: !! noTeaser
},
innerHTML: ''
}
}

Block_Void
= "<!--" WS+ "wp:" blockName:Block_Name WS+ attrs:(a:Block_Attributes WS+ {
/** <?php return $a; ?> **/
Expand Down
3 changes: 3 additions & 0 deletions blocks/api/raw-handling/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getBlockTypes, getUnknownTypeHandlerName } from '../registration';
import { getBlockAttributes, parseWithGrammar } from '../parser';
import normaliseBlocks from './normalise-blocks';
import stripAttributes from './strip-attributes';
import specialCommentConverter from './special-comment-converter';
import commentRemover from './comment-remover';
import createUnwrapper from './create-unwrapper';
import isInlineContent from './is-inline-content';
Expand Down Expand Up @@ -96,6 +97,7 @@ export default function rawHandler( { HTML, plainText = '', mode = 'AUTO', tagNa
// Add semantic formatting before attributes are stripped.
formattingTransformer,
stripAttributes,
specialCommentConverter,
commentRemover,
createUnwrapper( ( node ) => ! isInline( node, tagName ) ),
] );
Expand Down Expand Up @@ -124,6 +126,7 @@ export default function rawHandler( { HTML, plainText = '', mode = 'AUTO', tagNa
// Add semantic formatting before attributes are stripped.
formattingTransformer,
stripAttributes,
specialCommentConverter,
commentRemover,
! canUserUseUnfilteredHTML && createUnwrapper( ( element ) => element.nodeName === 'IFRAME' ),
embeddedContentReducer,
Expand Down
73 changes: 73 additions & 0 deletions blocks/api/raw-handling/special-comment-converter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Browser dependencies
*/
const { COMMENT_NODE } = window.Node;

/**
* Looks for `<!--more-->` comments, as well as the `<!--more Some text-->`
* variant and its `<!--noteaser-->` companion, and replaces them with a custom
* element representing a future block.
*
* The custom element is a way to bypass the rest of the `raw-handling`
* transforms, which would eliminate other kinds of node with which to carry
* `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc.
*
* The custom element is then expected to be recognized by any registered
* block's `raw` transform.
*
* @param {Node} node The node to be processed.
* @return {void}
*/
export default function( node ) {
if (
node.nodeType !== COMMENT_NODE ||
node.nodeValue.indexOf( 'more' ) !== 0
) {
// We don't specificially look for `noteaser`, meaning that if one is
// found on its own (and not adjacent to `more`), it will be lost.
return;
}

// Grab any custom text in the comment
const customText = node.nodeValue.slice( 4 ).trim();

// When a `<!--more-->` comment is found, we need to look for any
// `<!--noteaser-->` sibling, but it may not be a direct sibling
// (whitespace typically lies in between)
let sibling = node;
let noTeaser = false;
while ( ( sibling = sibling.nextSibling ) ) {
if (
sibling.nodeType === COMMENT_NODE &&
sibling.nodeValue === 'noteaser'
) {
noTeaser = true;
sibling.parentNode.removeChild( sibling );
break;
}
}

// Conjure up a custom More element
const more = createMore( customText, noTeaser );

// Append it to the top level for later conversion to blocks
let parent = node.parentNode;
while ( parent.nodeName !== 'BODY' ) {
parent = parent.parentNode;
}
parent.appendChild( more );
node.parentNode.removeChild( node );
}

function createMore( customText, noTeaser ) {
const node = document.createElement( 'wp-block' );
node.dataset.block = 'core/more';
if ( customText ) {
node.dataset.customText = customText;
}
if ( noTeaser ) {
// "Boolean" data attribute
node.dataset.noTeaser = '';
}
return node;
}
49 changes: 49 additions & 0 deletions blocks/api/raw-handling/test/special-comment-converter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* External dependencies
*/
import { equal } from 'assert';

/**
* Internal dependencies
*/
import specialCommentConverter from '../special-comment-converter';
import { deepFilterHTML } from '../utils';

describe( 'specialCommentConverter', () => {
it( 'should convert a single comment into a basic block', () => {
equal(
deepFilterHTML( '<!--more-->', [ specialCommentConverter ] ),
'<wp-block data-block="core/more"></wp-block>'
);
} );
it( 'should convert two comments into a block', () => {
equal(
deepFilterHTML( '<!--more--><!--noteaser-->', [ specialCommentConverter ] ),
'<wp-block data-block="core/more" data-no-teaser=""></wp-block>'
);
} );
it( 'should pass custom text to the block', () => {
equal(
deepFilterHTML(
'<!--more Read all about it!--><!--noteaser-->',
[ specialCommentConverter ]
),
'<wp-block data-block="core/more" data-custom-text="Read all about it!" data-no-teaser=""></wp-block>'
);
} );
it( 'should handle reformatted content', () => {
const output = deepFilterHTML(
`<p>
<!--more-->
<!--noteaser-->
</p>`,
[ specialCommentConverter ]
);
// Skip the empty paragraph, which other transforms would eliminate
const start = output.indexOf( '</p>' ) + '</p>'.length;
equal(
output.substr( start ),
'<wp-block data-block="core/more" data-no-teaser=""></wp-block>'
);
} );
} );
75 changes: 58 additions & 17 deletions blocks/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,19 @@ let unknownTypeHandlerName;
*/
let defaultBlockName;

/**
* Constant mapping post formats to the expected default block.
*
* @type {Object}
*/
const POST_FORMAT_BLOCK_MAP = {
audio: 'core/audio',
gallery: 'core/gallery',
image: 'core/image',
quote: 'core/quote',
video: 'core/video',
};

/**
* Registers a new block provided a unique name and an object defining its
* behavior. Once registered, the block is made available as an option to any
Expand Down Expand Up @@ -93,21 +106,24 @@ export function registerBlockType( name, settings ) {
);
return;
}
if ( ! settings || ! isFunction( settings.save ) ) {
if ( blocks[ name ] ) {
console.error(
'The "save" property must be specified and must be a valid function.'
'Block "' + name + '" is already registered.'
);
return;
}
if ( 'edit' in settings && ! isFunction( settings.edit ) ) {

settings = applyFilters( 'blocks.registerBlockType', settings, name );

if ( ! settings || ! isFunction( settings.save ) ) {
console.error(
'The "edit" property must be a valid function.'
'The "save" property must be specified and must be a valid function.'
);
return;
}
if ( blocks[ name ] ) {
if ( 'edit' in settings && ! isFunction( settings.edit ) ) {
console.error(
'Block "' + name + '" is already registered.'
'The "edit" property must be a valid function.'
);
return;
}
Expand Down Expand Up @@ -145,8 +161,6 @@ export function registerBlockType( name, settings ) {
settings.icon = 'block-default';
}

settings = applyFilters( 'blocks.registerBlockType', settings, name );

return blocks[ name ] = settings;
}

Expand Down Expand Up @@ -201,12 +215,26 @@ export function setDefaultBlockName( name ) {
/**
* Retrieves the default block name.
*
* @return {?string} Blog name.
* @return {?string} Block name.
*/
export function getDefaultBlockName() {
return defaultBlockName;
}

/**
* Retrieves the expected default block for the post format.
*
* @param {string} postFormat Post format
* @return {string} Block name.
*/
export function getDefaultBlockForPostFormat( postFormat ) {
const blockName = POST_FORMAT_BLOCK_MAP[ postFormat ];
if ( blockName && getBlockType( blockName ) ) {
return blockName;
}
return null;
}

/**
* Returns a registered block type.
*
Expand All @@ -227,6 +255,26 @@ export function getBlockTypes() {
return Object.values( blocks );
}

/**
* Returns the block support value for a feature, if defined.
*
* @param {(string|Object)} nameOrType Block name or type object
* @param {string} feature Feature to retrieve
* @param {*} defaultSupports Default value to return if not
* explicitly defined
* @return {?*} Block support value
*/
export function getBlockSupport( nameOrType, feature, defaultSupports ) {
const blockType = 'string' === typeof nameOrType ?
getBlockType( nameOrType ) :
nameOrType;

return get( blockType, [
'supports',
feature,
], defaultSupports );
}

/**
* Returns true if the block defines support for a feature, or false otherwise.
*
Expand All @@ -238,14 +286,7 @@ export function getBlockTypes() {
* @return {boolean} Whether block supports feature.
*/
export function hasBlockSupport( nameOrType, feature, defaultSupports ) {
const blockType = 'string' === typeof nameOrType ?
getBlockType( nameOrType ) :
nameOrType;

return !! get( blockType, [
'supports',
feature,
], defaultSupports );
return !! getBlockSupport( nameOrType, feature, defaultSupports );
}

/**
Expand Down
15 changes: 1 addition & 14 deletions blocks/api/serializer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { isEmpty, reduce, isObject, castArray, compact, startsWith } from 'lodash';
import { isEmpty, reduce, isObject, castArray, startsWith } from 'lodash';
import { html as beautifyHtml } from 'js-beautify';
import isEqualShallow from 'is-equal-shallow';

Expand Down Expand Up @@ -239,19 +239,6 @@ export function serializeBlock( block ) {
const saveAttributes = getCommentAttributes( block.attributes, blockType );

switch ( blockName ) {
case 'core/more':
const { customText, noTeaser } = saveAttributes;

const moreTag = customText ?
`<!--more ${ customText }-->` :
'<!--more-->';

const noTeaserTag = noTeaser ?
'<!--noteaser-->' :
'';

return compact( [ moreTag, noTeaserTag ] ).join( '\n' );

case getUnknownTypeHandlerName():
return saveContent;

Expand Down
Loading