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

Add pagination block #1467

Merged
merged 1 commit into from
Apr 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 36 additions & 33 deletions blocks/api/raw-handling/special-comment-converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { remove, replace } from '@wordpress/utils';
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.
* Looks for `<!--nextpage-->` and `<!--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
Expand All @@ -24,43 +24,39 @@ const { COMMENT_NODE } = window.Node;
* @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.
if ( node.nodeType !== COMMENT_NODE ) {
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;
remove( sibling );
break;
}
if ( node.nodeValue === 'nextpage' ) {
replace( node, createNextpage() );
return;
}

// Conjure up a custom More element
const more = createMore( customText, noTeaser );
if ( node.nodeValue.indexOf( 'more' ) === 0 ) {
// 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;
remove( sibling );
break;
}
}

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

function createMore( customText, noTeaser ) {
Expand All @@ -75,3 +71,10 @@ function createMore( customText, noTeaser ) {
}
return node;
}

function createNextpage() {
const node = document.createElement( 'wp-block' );
node.dataset.block = 'core/nextpage';

return node;
}
26 changes: 25 additions & 1 deletion blocks/api/raw-handling/test/special-comment-converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import specialCommentConverter from '../special-comment-converter';
import { deepFilterHTML } from '../utils';

describe( 'specialCommentConverter', () => {
it( 'should convert a single comment into a basic block', () => {
it( 'should convert a single "more" comment into a basic block', () => {
equal(
deepFilterHTML(
'<p><!--more--></p>',
Expand All @@ -19,6 +19,12 @@ describe( 'specialCommentConverter', () => {
'<p></p><wp-block data-block="core/more"></wp-block>'
);
} );
it( 'should convert a single "nextpage" comment into a basic block', () => {
equal(
deepFilterHTML( '<p><!--nextpage--></p>', [ specialCommentConverter ] ),
'<p></p><wp-block data-block="core/nextpage"></wp-block>'
);
} );
it( 'should convert two comments into a block', () => {
equal(
deepFilterHTML(
Expand Down Expand Up @@ -79,5 +85,23 @@ describe( 'specialCommentConverter', () => {
<p>Third paragraph</p>`
);
} );
it( 'should not break pagination order', () => {
const output = deepFilterHTML(
`<p>First page.</p>
<p><!--nextpage--></p>
<p>Second page</p>
<p><!--nextpage--></p>
<p>Third page</p>`,
[ specialCommentConverter ]
);
equal(
output,
`<p>First page.</p>
<p></p><wp-block data-block=\"core/nextpage\"></wp-block>
<p>Second page</p>
<p></p><wp-block data-block=\"core/nextpage\"></wp-block>
<p>Third page</p>`
);
} );
} );
} );
2 changes: 2 additions & 0 deletions blocks/library/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as html from './html';
import * as latestPosts from './latest-posts';
import * as list from './list';
import * as more from './more';
import * as nextpage from './nextpage';
import * as preformatted from './preformatted';
import * as pullquote from './pullquote';
import * as sharedBlock from './block';
Expand Down Expand Up @@ -60,6 +61,7 @@ export const registerCoreBlocks = () => {
html,
latestPosts,
more,
nextpage,
preformatted,
pullquote,
separator,
Expand Down
40 changes: 40 additions & 0 deletions blocks/library/nextpage/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.editor-visual-editor__block[data-type="core/nextpage"] {
max-width: 100%;
}

.wp-block-nextpage {
display: block;
text-align: center;
overflow: hidden;
white-space: nowrap;
}

.wp-block-nextpage > span {
position: relative;
display: inline-block;
font-size: 12px;
text-transform: uppercase;
font-weight: 600;
font-family: $default-font;
color: $dark-gray-300;
}

.wp-block-nextpage > span:before,
.wp-block-nextpage > span:after {
content: '';
position: absolute;
top: 50%;
width: 100vw;
border-top: 3px dashed $light-gray-700;
margin-top: -2px;
}

.wp-block-nextpage > span:before {
right: 100%;
margin-right: 20px;
}

.wp-block-nextpage > span:after {
left: 100%;
margin-left: 20px;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is a lot different from blocks/library/more/editor.scss. I prefer the final result for Next Page, and we'd probably want to converge a bit on the two stylesheets. Any advice from @jasmussen is much appreciated, as always.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it would be nice to refine the styles of both of these blocks. However this PR has gone on for a while. I think perhaps it'd be good to merge this in as is, and then look at refining/unifying the styles separately. I can take that on as a quick smallish PR.

61 changes: 61 additions & 0 deletions blocks/library/nextpage/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { RawHTML } from '@wordpress/element';

/**
* Internal dependencies
*/
import './editor.scss';
import { createBlock } from '../../api';

export const name = 'core/nextpage';

export const settings = {
title: __( 'Page break' ),

description: __( 'This block allows you to set break points on your post. Visitors of your blog are then presented with content split into multiple pages.' ),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A keyword property here would be useful to include things like next page, helping with discovery in the block inserters.

icon: 'admin-page',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

admin-page seems alright to me, but if @jasmussen has some other suggestion, 🙇

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that icon is solid.


category: 'layout',

keywords: [ __( 'next page' ), __( 'pagination' ) ],

supports: {
customClassName: false,
className: false,
html: false,
},

attributes: {},

transforms: {
from: [
{
type: 'raw',
isMatch: ( node ) => node.dataset && node.dataset.block === 'core/nextpage',
transform() {
return createBlock( 'core/nextpage', {} );
},
},
],
},

edit() {
return (
<div className="wp-block-nextpage">
<span>{ __( 'Page break' ) }</span>
</div>
);
},

save() {
return (
<RawHTML>
{ '<!--nextpage-->' }
</RawHTML>
);
},
};
11 changes: 11 additions & 0 deletions blocks/library/nextpage/test/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`core/nextpage block edit matches snapshot 1`] = `
<div
class="wp-block-nextpage"
>
<span>
Page break
</span>
</div>
`;
13 changes: 13 additions & 0 deletions blocks/library/nextpage/test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Internal dependencies
*/
import { name, settings } from '../';
import { blockEditRender } from 'blocks/test/helpers';

describe( 'core/nextpage', () => {
test( 'block edit matches snapshot', () => {
const wrapper = blockEditRender( name, settings );

expect( wrapper ).toMatchSnapshot();
} );
} );
3 changes: 3 additions & 0 deletions blocks/test/fixtures/core__nextpage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<!-- wp:core/nextpage -->
<!--nextpage-->
<!-- /wp:core/nextpage -->
10 changes: 10 additions & 0 deletions blocks/test/fixtures/core__nextpage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"uid": "_uid_0",
"name": "core/nextpage",
"isValid": true,
"attributes": {},
"innerBlocks": [],
"originalContent": "<!--nextpage-->"
}
]
12 changes: 12 additions & 0 deletions blocks/test/fixtures/core__nextpage.parsed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"blockName": "core/nextpage",
"attrs": null,
"innerBlocks": [],
"innerHTML": "\n<!--nextpage-->\n"
},
{
"attrs": {},
"innerHTML": "\n"
}
]
3 changes: 3 additions & 0 deletions blocks/test/fixtures/core__nextpage.serialized.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<!-- wp:nextpage -->
<!--nextpage-->
<!-- /wp:nextpage -->