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 "TinyMCE per block" prototype #80

Merged
merged 2 commits into from
Feb 17, 2017
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
14 changes: 14 additions & 0 deletions tinymce-per-block/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"presets": [
[ "es2015", {
"modules": false
} ],
"stage-2"
],
"plugins": [
[ "transform-react-jsx", {
"pragma": "createElement"
} ],
"lodash"
]
}
16 changes: 16 additions & 0 deletions tinymce-per-block/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# http://editorconfig.org
root = true

[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[package.json]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
1 change: 1 addition & 0 deletions tinymce-per-block/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/parsers/block/grammar.js
19 changes: 19 additions & 0 deletions tinymce-per-block/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"root": true,
"extends": "wpcalypso/react",
"parser": "babel-eslint",
"env": {
"browser": true,
"node": true
},
"settings": {
"react": {
"pragma": "createElement"
}
},
"rules": {
"camelcase": 0,
"max-len": [ 2, { "code": 120 } ],
"react/jsx-no-bind": 0
}
}
57 changes: 57 additions & 0 deletions tinymce-per-block/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"TinyMCE Per Block" Prototype
=============================

This is a WordPress editor technical prototype to explore the feasability of decorating blocks as editable, initializing TinyMCE on only those blocks for which it is required.

## Demo

https://wordpress.github.io/gutenberg/tinymce-per-block/

## Background

This prototype implements ideas explored in the Make WordPress Core's [Editor Technical Overview](https://make.wordpress.org/core/2017/01/17/editor-technical-overview/) blog post. Instead of expecting TinyMCE to manage the entire markup of a post, this prototype instead uses a [formal post grammar](https://github.com/Automattic/wp-post-grammar) to parse a post's content in the browser client. The JavaScript data structure of the post content is then used to render a set of controls which form the visual representation of the editor. The look and feel of these controls can be extended through an included block registration API, with backwards compatibility for posts preserved by either a generic block type or automated migration (a solution is yet to be decided).

Examples:

- [Text Block](./src/blocks/text-block)
- [Image Block](./src/blocks/image-block)

## Status

This prototype currently implements:

- Content parsing
- Block registration
- Editor block list rendering
- Binding TinyMCE to blocks ([see `wp-blocks/bind-editable`](./src/external/wp-blocks/bind-editable))
- Block-level control changes (e.g. text centering)
- Serializing block content

The prototype lacks:

- Block reordering
- Inserting new blocks (including creating or splitting paragraphs)
- Selecting across paragraphs of text
- Backwards compatibility for non-block content

## Development

You must first [download and install Node.js](https://nodejs.org/en/download/) before you can build or develop this prototype. Next, in your terminal, navigate to the project directory and install dependencies:

```
npm install
```

**To develop with automatic recompilation:**

```
npm run dev
```

You can now visit [http://localhost:8081](http://localhost:8081) in your browser.

**To compile changes for commit:**

```
npm run build
```
19 changes: 19 additions & 0 deletions tinymce-per-block/build/app.js

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions tinymce-per-block/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blocks</title>
</head>
<body>
<div class="renderers">
<div id="html"></div>
<div id="block"></div>
</div>
<script>
window.content = '<!-- wp:text -->A beautiful thing about Apple is how quickly they obsolete their own products. I imagine this also makes the discipline of getting things out there easier. Like I mentioned before, the longer it’s been since the last release the more pressure there is, but if you know that if your bit of code doesn’t make this version but there’s the +0.1 coming out in 6 weeks, then it’s not that bad. It’s like flights from San Francisco to LA, if you miss one you know there’s another one an hour later so it’s not a big deal. Amazon has done a fantastic job of this with the Kindle as well, with a new model every year.<!-- /wp -->\n\n<!-- wp:text -->I like Apple for the opposite reason: <strong>they’re not afraid of getting a rudimentary 1.0 out into the world</strong>.<!-- /wp -->\n\n<!-- wp:image --><img src="https://matiasventura.files.wordpress.com/2017/02/blue.png?w=720"><!-- /wp -->';
</script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Merriweather:300,300i,400,400i,700,700i">
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.5.3/tinymce.min.js"></script>
<script src="build/app.js"></script>
</body>
</html>
57 changes: 57 additions & 0 deletions tinymce-per-block/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "gutenberg",
"version": "1.0.0",
"description": "Prototyping a new WordPress editor experience",
"main": "index.html",
"scripts": {
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production webpack",
"clean": "rimraf build",
"predev": "npm run clean",
"dev": "webpack-dev-server --content-base ./"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Automattic/gutenberg.git"
},
"keywords": [
"WordPress",
"editor",
"prototype"
],
"author": "WordPress Contributors",
"license": "GPL-2.0+",
"bugs": {
"url": "https://github.com/WordPress/gutenberg/issues"
},
"homepage": "https://github.com/WordPress/gutenberg#readme",
"devDependencies": {
"autoprefixer": "^6.7.2",
"babel-core": "^6.22.1",
"babel-eslint": "^7.1.1",
"babel-loader": "^6.2.10",
"babel-plugin-lodash": "^3.2.11",
"babel-plugin-transform-react-jsx": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"babel-preset-stage-2": "^6.22.0",
"cross-env": "^3.1.4",
"css-loader": "^0.26.1",
"eslint": "^3.15.0",
"eslint-config-wpcalypso": "^0.6.0",
"eslint-plugin-react": "^6.9.0",
"eslint-plugin-wpcalypso": "^3.0.2",
"node-sass": "^4.5.0",
"postcss-loader": "^1.2.2",
"rimraf": "^2.5.4",
"sass-loader": "^4.1.1",
"style-loader": "^0.13.1",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.3.0"
},
"dependencies": {
"classnames": "^2.2.5",
"is-equal-shallow": "^0.1.3",
"lodash": "^4.17.4",
"preact": "^7.1.0"
}
}
15 changes: 15 additions & 0 deletions tinymce-per-block/src/assets/stylesheets/_animations.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@mixin animate_fade {
animation: animate_fade 0.2s ease-out;
animation-fill-mode: forwards;
}

@keyframes animate_fade {
from {
opacity: 0;
transform: scale( 0.92 )
}
to {
opacity: 1;
transform: scale( 1 )
}
}
4 changes: 4 additions & 0 deletions tinymce-per-block/src/assets/stylesheets/_variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Colors
$gray-light: #f0f2f4;
$gray-dark-300: #6c7781;
$gray-dark-900: #191e23;
52 changes: 52 additions & 0 deletions tinymce-per-block/src/assets/stylesheets/main.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@import 'variables';
@import 'animations';
@import '~blocks/text-block/style';
@import '~blocks/image-block/style';
@import '~external/dashicons/style';
@import '~renderers/block/block-list/style';
@import '~renderers/html/html-editor/style';

html {
height: 100%;
font-size: 10px;
}

body {
margin: 4vh auto;
min-height: 92vh;
width: 90%;
max-width: 1280px;
-webkit-font-smoothing: antialiased !important;
}

.renderers {
position: relative;
display: flex;
min-height: 100%;

&::after {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 50%;
margin-left: -2px;
width: 4px;
background-color: $gray-light;
}

> #html,
> #block {
flex-basis: 50%;
margin: 0 8rem;
padding: 4vh 0;

&:first-child {
margin-left: 0;
}

&:last-child {
margin-right: 0;
}
}
}
4 changes: 4 additions & 0 deletions tinymce-per-block/src/blocks/image-block/_style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.image-block__display {
display: block;
max-width: 100%;
}
18 changes: 18 additions & 0 deletions tinymce-per-block/src/blocks/image-block/form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* External dependencies
*/
import { createElement } from 'wp-elements';
import { find } from 'lodash';

export default function ImageBlockForm( { children } ) {
const image = find( children, ( { name } ) => 'img' === name );
if ( ! image ) {
return null;
}

return (
<img
src={ image.attrs.src }
className="image-block__display" />
);
}
16 changes: 16 additions & 0 deletions tinymce-per-block/src/blocks/image-block/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* External dependencies
*/
import { registerBlock } from 'wp-blocks';
import { FormatImageIcon } from 'dashicons';

/**
* Internal dependencies
*/
import form from './form';

registerBlock( 'image', {
title: 'Image',
icon: FormatImageIcon,
form
} );
4 changes: 4 additions & 0 deletions tinymce-per-block/src/blocks/text-block/_style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.text-block__form {
margin: 0;
outline: none;
}
43 changes: 43 additions & 0 deletions tinymce-per-block/src/blocks/text-block/form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* External dependencies
*/
import { createElement } from 'wp-elements';
import { unescape as unescapeString, reduce, map } from 'lodash';

function getChildElements( child ) {
if ( child.value ) {
return unescapeString( child.value );
}

let children;
if ( child.children ) {
children = map( child.children, getChildElements );
}

if ( 'HTML_Tag' === child.type ) {
return createElement( child.name, child.attrs, children );
}

return children;
}

export default function TextBlockForm( { node } ) {
const style = reduce( node.attrs, ( memo, value, key ) => {
switch ( key ) {
case 'align':
memo[ 'text-align' ] = value;
break;
}

return memo;
}, {} );

return (
<p
contentEditable
style={ style }
className="text-block__form">
{ map( node.children, getChildElements ) }
</p>
);
}
Loading