Skip to content

Commit

Permalink
Merge pull request #219 from lanfisis/master
Browse files Browse the repository at this point in the history
Switch form PEL to SunEditor as default WYSIWYG editor
  • Loading branch information
lanfisis authored Apr 25, 2024
2 parents bbade9a + 9651350 commit 293b0f2
Show file tree
Hide file tree
Showing 22 changed files with 394 additions and 106 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
/.phpunit.result.cache
/node_modules
/yarn.lock

/src/Resources/public/js/*.txt
16 changes: 14 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ reset: ## Stop docker and remove dependencies
${MAKE} docker.down || true
rm -rf ${APP_DIR}/node_modules ${APP_DIR}/yarn.lock
rm -rf ${APP_DIR}
rm -rf vendor composer.lock
rm -rf vendor composer.lock node_modules yarn.lock
.PHONY: reset

dependencies: composer.lock node_modules ## Setup the dependencies
Expand Down Expand Up @@ -132,7 +132,7 @@ test.container: ## Lint the symfony container
${CONSOLE} lint:container

test.yaml: ## Lint the symfony Yaml files
${CONSOLE} lint:yaml ../../recipes ../../src/Resources/config
${CONSOLE} lint:yaml --parse-tags ../../recipes ../../src/Resources/config

test.schema: ## Validate MySQL Schema
${CONSOLE} doctrine:schema:validate
Expand Down Expand Up @@ -200,6 +200,18 @@ server.start: ## Run the local webserver using Symfony
server.stop: ## Stop the local webserver
${SYMFONY} local:server:stop

###
### THEMING
### ¯¯¯¯¯¯¯

.PHONY: sylius.theming.build
sylius.theming.build: yarn.install
${YARN} build

.PHONY: sylius.theming.watch
sylius.theming.watch: yarn.install
${YARN} watch

###
### HELP
### ¯¯¯¯
Expand Down
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,49 @@ In the YAML declaration of a UI Element, you can add the wireframe key with the
front_render: '@MonsieurBizSyliusRichEditorPlugin/Shop/UiElement/title.html.twig'
```

## Wysiwyg Type

The `WysiwygType` form type is a custom form type provided by the MonsieurBiz Sylius Rich Editor plugin. It extends the
Symfony's `TextareaType` and provides a rich text editor interface in the admin form. It will work only in admin.

### Basic Usage

To use the `WysiwygType` in your form, you can add it to your form builder like this:

```php
$builder->add('content', WysiwygType::class, [
'required' => false,
'label' => 'app.form.content',
]);
```
### Options

The `WysiwygType` form type accepts several options:

- `editor_type`: The type of the editor. Default is `SunEditor::TYPE`. At this time, the only supported editor type is `SunEditor::TYPE`.
- `editor_height`: The height of the editor in pixels. Default is `300`.
- `editor_locale`: The locale of the editor. Default is the current admin locale or 'en' if it cannot be determined.
- `editor_toolbar_type`: The type of the toolbar. It can be one of the following: `EditorInterface::TOOLBAR_TYPE_MINIMAL`, `EditorInterface::TOOLBAR_TYPE_BASIC`, `EditorInterface::TOOLBAR_TYPE_FULL`, `EditorInterface::TOOLBAR_TYPE_CUSTOM`. Default is `EditorInterface::TOOLBAR_TYPE_BASIC`.
- `editor_toolbar_buttons`: An array of buttons to be displayed in the toolbar when `editor_toolbar_type` is `EditorInterface::TOOLBAR_TYPE_CUSTOM`. Default is `null`.
- `editor_custom_config`: An array of custom configuration options for the editor. Default is `null`.

Here is an example of how to use these options:

```php
$builder->add('content', WysiwygType::class, [
'required' => false,
'label' => 'app.form.content',
'editor_height' => 500,
'editor_locale' => 'fr',
'editor_toolbar_type' => EditorInterface::TOOLBAR_TYPE_CUSTOM,
'editor_toolbar_buttons' => ['bold', 'italic', 'underline'],
'editor_custom_config' => ['option1' => 'value1', 'option2' => 'value2'],
]);
```

In this example, we have set a custom editor type, increased the height of the editor, set the locale to French, chosen
a full toolbar, specified the buttons to be displayed in the toolbar, and provided some custom configuration options for
the editor.

## Contributing

Expand Down
69 changes: 11 additions & 58 deletions assets/js/app.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,22 @@
import pell from 'pell';
import Dialog from 'a11y-dialog-component';
import Mustache from 'mustache';
import '../css/app.scss';

global.MonsieurBizRichEditorWysiwyg = class {
constructor(config) {
this.config = config; // {actions: []}
}

exec() {
return pell.exec(...arguments);
}
import suneditor from "./editors/editors/suneditor";

load(container) {
const targets = container.querySelectorAll('textarea.wysiwyg-enabled');
for (let target of targets) {
this.setupEditor(target);
}
}
const initEditors = (target) => {
suneditor.init(target);
}

setupEditor(target) {
target.setAttribute('hidden', 'true');

// Create container
const wysiwygContainer = document.createElement('div');
wysiwygContainer.classList.add('pell');
target.parentNode.appendChild(wysiwygContainer);

// Init pell wysiwyg
const editor = pell.init({
element: wysiwygContainer,
onChange: html => {
target.textContent = html
},
defaultParagraphSeparator: 'p',
actions: this.config.actions,
});

editor.addEventListener('paste', function (e) {
e.stopPropagation();
e.preventDefault();
let tempContainer = document.createElement('div');
let clipboardData = e.clipboardData || window.clipboardData;
tempContainer.innerHTML = clipboardData.getData('Text');
let text = tempContainer.textContent || tempContainer.innerText || "";
pell.exec('insertText', text);
return true;
});

// Populate wysiwyg with initial content
const initialContent = target.value;
editor.content.innerHTML = initialContent;
}

};
document.addEventListener('DOMContentLoaded', function () {
const target = document.querySelector('body');
initEditors(target);
});

global.MonsieurBizRichEditorConfig = class {
constructor(
input,
uielements,
wysiwyg,
containerHtml,
actionsHtml,
elementHtml,
Expand All @@ -76,7 +34,6 @@ global.MonsieurBizRichEditorConfig = class {
) {
this.input = input;
this.uielements = uielements;
this.wysiwyg = wysiwyg;
this.containerHtml = containerHtml;
this.actionsHtml = actionsHtml;
this.elementHtml = elementHtml;
Expand Down Expand Up @@ -400,10 +357,6 @@ global.MonsieurBizRichEditorManager = class {
return this.config.input;
}

get wysiwyg() {
return this.config.wysiwyg;
}

openSelectionPanel(position) {
this.selectionPanel.dialog.manager = this;
this.selectionPanel.dialog.position = position;
Expand Down Expand Up @@ -439,7 +392,7 @@ global.MonsieurBizRichEditorManager = class {
drawNewForm(formHtml, position) {
this.newPanel.dialog.innerHTML = formHtml;
let form = this.newPanel.dialog;
this.wysiwyg.load(form);
initEditors(form);
this.dispatchInitFormEvent(form, this);

// Form submit
Expand Down Expand Up @@ -506,7 +459,7 @@ global.MonsieurBizRichEditorManager = class {
this.editPanel.dialog.querySelector('.js-uie-content').innerHTML = formHtml;
let form = this.editPanel.dialog;

this.wysiwyg.load(form);
initEditors(form);
this.dispatchInitFormEvent(form, this);

// Form submit
Expand Down
49 changes: 49 additions & 0 deletions assets/js/editors/editors/suneditor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'suneditor/src/assets/css/suneditor.css'
import 'suneditor/src/assets/css/suneditor-contents.css'
import suneditor from 'suneditor'
import lang from 'suneditor/src/lang'
import suneditorPlugins from 'suneditor/src/plugins'
import CodeMirror from 'codemirror'
import 'codemirror/mode/htmlmixed/htmlmixed'
import 'codemirror/lib/codemirror.css'

const currentEditors = [];

const initEditor = () => {
return suneditor.init({
codeMirror: CodeMirror,
height: 'auto',
plugins: suneditorPlugins,
buttonList: []
});
}

export default {
init(target) {
const editorModel = initEditor();
target.querySelectorAll('[data-component="wysiwyg-editor"][data-editor-type="suneditor"]').forEach((component) => {

// SundEditor is ID based, so we need to make sure that the ID is unique
if (currentEditors.includes(component.id)) {
component.id = `${component.id}-${Math.random().toString(36).substring(7)}`;
}

const buttonList = JSON.parse(component.dataset.editorButtons);
const height = component.dataset.editorHeight;
const locale = component.dataset.editorLocale;
const customConfig = JSON.parse(component.dataset.editorCustomConfig);
const config = {
height,
buttonList,
lang: lang[locale],
...customConfig
};
const editor = editorModel.create(component, config);
editor.onChange = () => {
editor.save();
};

currentEditors.push(component.id);
})
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
},
"dependencies": {
"a11y-dialog-component": "^5.5.1",
"codemirror": "5",
"gulp": "^4.0.2",
"mustache": "^4.0.1",
"pell": "^1.0.6"
"suneditor": "^2.45.1"
}
}
6 changes: 4 additions & 2 deletions src/Form/Type/UiElement/HtmlType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@

namespace MonsieurBiz\SyliusRichEditorPlugin\Form\Type\UiElement;

use MonsieurBiz\SyliusRichEditorPlugin\Form\Type\WysiwygType;
use MonsieurBiz\SyliusRichEditorPlugin\WysiwygEditor\EditorInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;

class HtmlType extends AbstractType
Expand All @@ -25,8 +26,9 @@ class HtmlType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('content', TextareaType::class, [
->add('content', WysiwygType::class, [
'label' => 'monsieurbiz_richeditor_plugin.ui_element.monsieurbiz.html.field.content',
'editor_toolbar_type' => EditorInterface::TOOLBAR_TYPE_FULL,
])
;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Form/Type/UiElement/TextType.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use MonsieurBiz\SyliusRichEditorPlugin\Form\Type\AlignmentType;
use MonsieurBiz\SyliusRichEditorPlugin\Form\Type\WysiwygType;
use MonsieurBiz\SyliusRichEditorPlugin\WysiwygEditor\EditorInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints as Assert;
Expand All @@ -30,6 +31,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
->add('content', WysiwygType::class, [
'required' => true,
'label' => 'monsieurbiz_richeditor_plugin.ui_element.monsieurbiz.text.field.content',
'editor_toolbar_type' => EditorInterface::TOOLBAR_TYPE_MINIMAL,
'constraints' => [
new Assert\NotBlank([]),
],
Expand Down
Loading

0 comments on commit 293b0f2

Please sign in to comment.