Replace isolated-block-editor in favor of @wordpress/block-editor

Despite the fact that Gutenberg developers did not care at all about
uses of this library outside WordPress until last year[0], and that it
is almost impossible to do something that goes beyond the very basic
without using “private APIs”, they insist that the isolated block
editor should be “deprecated”[1].

I do not particularly care much about the isolated block editor, as it
_does_ use all these private APIs and, thus, it is very difficult to
use unless you use the exact same dependencies, otherwise it emits a
weird error regarding “unlocking” things that are not “locked” (i.e.,
the new-fangled way of “protecting” private APIs[2]).  And,
apparently, things got easier with Gutenberg 18.5 with the
introduction of the BlockCanvas.

However, it is still a very frustrating experience, and the
documentation for most components and packages is next to
non-existent.

Nevertheless, i managed to get a barely functional editor that still
has some missing features, like the color of rich texts’ highlight
format[3], but it i believe it is a good base to grow the custom
editor on top of.

[0]: https://github.com/WordPress/gutenberg/issues/53874
[1]: https://github.com/WordPress/gutenberg/issues/57672#issuecomment-1883119040
[2]: https://developer.wordpress.org/block-editor/reference-guides/packages/packages-private-apis/
[3]: https://github.com/WordPress/gutenberg/issues/55036
This commit is contained in:
jordi fita mas 2024-06-14 03:24:07 +02:00
parent 98f4e8afab
commit 88025b57a4
13 changed files with 5038 additions and 13116 deletions

4
.gitignore vendored
View File

@ -1,5 +1,5 @@
/node_modules/
/po/*.pot
/web/static/editor.css
/web/static/editor.js
/web/static/index.html
/web/static/assets/
/web/static/*.json

View File

@ -1,13 +0,0 @@
module.exports = (api) => {
api.cache(true);
return {
plugins: [
[
"@wordpress/babel-plugin-makepot",
{"output": "po/editor.pot"}
],
],
presets: ['@wordpress/babel-preset-default'],
};
};

11
editor/BlockEditor.jsx Normal file
View File

@ -0,0 +1,11 @@
import { useSelect } from '@wordpress/data';
import { BlockCanvas, store as blockEditorStore } from '@wordpress/block-editor';
export default function BlockEditor({ rootClientId }) {
const styles = useSelect(( select ) => {
const { getSettings } = select( blockEditorStore );
return getSettings().styles;
});
console.log(styles);
return <BlockCanvas height="100%" styles={styles} />
}

33
editor/Editor.jsx Normal file
View File

@ -0,0 +1,33 @@
import { useState } from '@wordpress/element';
import { BlockEditorProvider } from '@wordpress/block-editor';
import BlockEditor from './BlockEditor';
import './editor.scss';
import blockLibraryCommon from '@wordpress/block-library/build-style/common.css?inline';
import blockLibraryEditor from '@wordpress/block-library/build-style/editor.css?inline';
import blockLibraryStyle from '@wordpress/block-library/build-style/style.css?inline';
import componentsStyle from '@wordpress/components/build-style/style.css?inline';
import formatLibraryStyle from '@wordpress/format-library/build-style/style.css?inline';
export default function Editor() {
const [ blocks, updateBlocks ] = useState();
return <BlockEditorProvider
value={ blocks }
onInput={ updateBlocks }
onChange={ updateBlocks }
settings={ {
styles: [
{ css: componentsStyle },
{ css: blockLibraryCommon },
{ css: blockLibraryStyle },
{ css: blockLibraryEditor },
{ css: formatLibraryStyle },
],
} }
>
<BlockEditor/>
</BlockEditorProvider>;
}

16
editor/editor.scss Normal file
View File

@ -0,0 +1,16 @@
@import '@wordpress/block-editor/build-style/style.css';
@import '@wordpress/block-editor/build-style/content.css';
@import '@wordpress/components/build-style/style.css';
body, html {
height: 100%;
margin: 0;
padding: 0;
}
main {
position: fixed;
inset: 0;
display: flex;
flex-direction: column;
}

13
editor/index.html Normal file
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tipus</title>
<link rel="icon" href="data:,">
</head>
<body>
<main></main>
<script type="module" src="main.jsx"></script>
</body>
</html>

View File

@ -1,77 +0,0 @@
import {render} from '@wordpress/element';
import {__, setLocaleData} from '@wordpress/i18n';
import './style.scss';
import IsolatedBlockEditor, {ToolbarSlot} from '@automattic/isolated-block-editor';
import {Button} from '@wordpress/components';
const settings = {
iso: {
sidebar: {
inspector: true,
inserter: true,
},
toolbar: {
inspector: true,
navigation: true,
},
moreMenu: {
editor: true,
preview: true,
},
},
};
const textarea = document.getElementById('content');
textarea.style.display = 'none';
const editor = document.createElement('div');
editor.classList.add('editor');
document.body.appendChild(editor);
function onLoad(content, parser, rawHandler) {
// Does the content contain blocks?
if (content.indexOf('<!--') !== -1) {
// Parse the blocks
return parser(content);
}
// Raw HTML - do our best
return rawHandler({HTML: content});
}
function saveBlocks(content, textarea) {
textarea.value = content;
}
function save() {
const requestOptions = {
method: 'PUT',
headers: {'Content-Type': 'text/html'},
body: textarea.value,
};
fetch('/edit', requestOptions);
}
async function load(editor) {
const response = await fetch('/static/es.json');
const result = await response.json();
const localeData = result.locale_data.messages;
localeData[""].domain = "default";
setLocaleData(localeData, 'default');
render(
<IsolatedBlockEditor
settings={settings}
onLoad={(parser, rawHandler) => onLoad(textarea.value, parser, rawHandler)}
onSaveContent={(content) => saveBlocks(content, textarea)}
onError={() => document.location.reload()}
>
<ToolbarSlot>
<Button onClick={save} variant="primary">{__('Beep!')}</Button>
</ToolbarSlot>
</IsolatedBlockEditor>,
editor
);
}
load(editor);

14
editor/main.jsx Normal file
View File

@ -0,0 +1,14 @@
import { createRoot, StrictMode } from '@wordpress/element';
import { registerCoreBlocks } from '@wordpress/block-library';
import '@wordpress/format-library';
registerCoreBlocks();
import Editor from './Editor';
const root = createRoot(document.querySelector('main'));
root.render(
<StrictMode>
<Editor/>
</StrictMode>
);

View File

@ -1,7 +0,0 @@
@import '@wordpress/components/build-style/style.css';
@import '@wordpress/block-editor/build-style/style.css';
@import '@wordpress/block-library/build-style/style.css';
@import '@wordpress/block-library/build-style/editor.css';
@import '@wordpress/block-library/build-style/theme.css';
@import '@wordpress/format-library/build-style/style.css';
@import '@wordpress/edit-post/build-style/style.css';

13565
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,25 @@
{
"name": "tipus",
"version": "0.0.0",
"type": "module",
"description": "Single page editor",
"author": "Tàndem",
"license": "GPL-3.0-only",
"license": "AGPL-3.0-or-later",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@automattic/isolated-block-editor": "^2.24.0",
"@wordpress/block-editor": "11.8.0",
"@wordpress/block-library": "8.8.0",
"@wordpress/components": "23.8.0",
"@wordpress/edit-post": "7.8.0",
"@wordpress/element": "5.8.0",
"@wordpress/format-library": "4.8.0",
"@wordpress/i18n": "4.31.0"
"@wordpress/block-editor": "13.0.0",
"@wordpress/block-library": "9.0.0",
"@wordpress/components": "28.0.0",
"@wordpress/element": "6.0.0",
"@wordpress/format-library": "5.0.0"
},
"devDependencies": {
"@babel/core": "^7.21.4",
"@babel/plugin-transform-runtime": "^7.21.4",
"@babel/preset-env": "^7.21.4",
"@babel/preset-react": "^7.18.6",
"@emotion/styled": "^11.10.6",
"@shopify/polyfills": "^4.0.3",
"@wordpress/babel-preset-default": "^7.15.0",
"babel-loader": "^9.1.2",
"babel-plugin-inline-json-import": "^0.3.2",
"css-loader": "^6.7.3",
"mini-css-extract-plugin": "^2.7.5",
"po2json": "^0.4.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass-loader": "^13.2.2",
"terser-webpack-plugin": "^5.3.9",
"typescript": "^5.0.4",
"webpack": "^5.80.0",
"webpack-cli": "^5.0.2"
"@vitejs/plugin-react": "^4.3.1",
"sass": "^1.77.0",
"vite": "^5.2.0"
}
}

10
vite.config.mjs Normal file
View File

@ -0,0 +1,10 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
root: 'editor',
build: {
outDir: '../web/static',
},
plugins: [react()],
});

View File

@ -1,50 +0,0 @@
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const config = {
entry: {
editor: './editor/index.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'web/static'),
},
module: {
rules: [
{
test: /\.(js|mjs)$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.scss|\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
'sass-loader',
],
},
],
},
externals: {
react: 'React',
'react-dom': 'ReactDOM',
},
plugins: [
new webpack.DefinePlugin({
'process.env': {NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')},
}),
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
optimization: {
minimizer: [new TerserJSPlugin()],
},
};
module.exports = config;