Skip to content

Commit

Permalink
FEATURE: Add keyboard shortcut option (Sebobo#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin-K authored Feb 23, 2021
1 parent 78dd1f1 commit c542acb
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 60 deletions.
9 changes: 9 additions & 0 deletions Configuration/Settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ Neos:
Shel.Neos:HyphensEditor:
resource: resource://Shel.Neos.Hyphens/Public/HyphensEditor/Plugin.js

frontendConfiguration:
'Shel.Neos:HyphensEditor':
# `shortcut` can be used to create a keyboard shortcut to insert soft hyphen
# Use any falsy value like `null` or `false` to disable it
shortcut:
- 'Ctrl'
- 'Shift'
- 189 # This is the minus sign

fusion:
autoInclude:
Shel.Neos.Hyphens: true
Expand Down
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Hyphens CKEditor5 plugin for Neos CMS
# Hyphens CKEditor5 plugin for Neos CMS

[![Latest Stable Version](https://poser.pugx.org/shel/neos-hyphens/v/stable)](https://packagist.org/packages/shel/neos-hyphens)
[![Total Downloads](https://poser.pugx.org/shel/neos-hyphens/downloads)](https://packagist.org/packages/shel/neos-hyphens)
Expand All @@ -8,20 +8,20 @@

This package provides a button to insert soft hyphens for the inline editor in Neos CMS.

Many browser support some kind of hyphenation via CSS but it doesnt work reliably on all systems
Many browser support some kind of hyphenation via CSS but it doesnt work reliably on all systems
and not with all languages. See the [CanIuse](https://caniuse.com/#feat=css-hyphens) table for details.

Therefore this package provides a manual way to insert them. You should be careful with using the
Therefore this package provides a manual way to insert them. You should be careful with using the
CSS based hyphenation in combination with the manual hyphens as the result can be unexpected.

It's compatible with Neos CMS 3.3 and 4.x with the Neos.Ui 2+.

## Example
## Example

In the backend this plugin will add the option to add soft hyphens. They will look like this while editing:

![Visible hyphens while editing](Documentation/neos-backend-hyphens.jpg)
![Visible hyphens while editing](Documentation/neos-backend-hyphens.jpg)

And in the frontend will convert this:

![Unwanted hyphenation without soft hyphens](Documentation/neos-frontend-before.jpg)
Expand All @@ -32,8 +32,8 @@ Into this:

And in action:

![Expected hyphenation](Documentation/example.gif)
![Expected hyphenation](Documentation/example.gif)

## Advantages

* Your editors gain control over word breaks.
Expand All @@ -50,7 +50,7 @@ See [enhancement issue list](https://github.com/Sebobo/Shel.Neos.Hyphens/issues?
Run this in your site package

composer require --no-update shel/neos-hyphens

Then run `composer update` in your project directory.

## How to use
Expand All @@ -64,7 +64,9 @@ Enable it for a node with editable text like this:
inline:
editorOptions:
hyphens: true

This will add a new button to insert a soft hyphen. As an alternative, you can use the shortcut `Ctrl + Shift + -` to add a new soft hyphen. To change the keys of the shortcut, have a look at the [Settings.yaml](Configuration/Settings.yaml#L12) file.

## Customization

### Hyphen styling in the backend
Expand All @@ -73,13 +75,13 @@ You can provide your own styling by referencing your own stylesheet.
See the file `Override.Page.fusion` on how the default styling is included.

You can either override the configuration from your own package and just use your stylesheet
or you can add yours and use both.
or you can add yours and use both.

## Contributions

Contributions are very welcome!
Contributions are very welcome!

Please create detailed issues and PRs.
Please create detailed issues and PRs.

**If you use this package and want to support or speed up it's development, [get in touch with me](mailto:[email protected]).**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ const addPlugin = (Plugin, isEnabled) => (ckEditorConfiguration, options) => {
return ckEditorConfiguration;
};

export default ckEditorRegistry => {
export default (ckEditorRegistry, editorConfig) => {
const config = ckEditorRegistry.get('config');

config.set('hyphens', addPlugin(Hyphens, $get('hyphens')));
config.set('hyphens', addPlugin(Hyphens(editorConfig), $get('hyphens')));

return config;
};
5 changes: 3 additions & 2 deletions Resources/Private/Scripts/HyphensEditor/src/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import manifest from '@neos-project/neos-ui-extensibility';
import initializeRichtextToolbarRegistry from './manifest.richtextToolbar';
import initializeConfigRegistry from './manifest.config';

manifest('Shel.Neos:HyphenEditor', {}, globalRegistry => {
manifest('Shel.Neos:HyphenEditor', {}, (globalRegistry, {frontendConfiguration}) => {
const ckEditorRegistry = globalRegistry.get('ckEditor5');
const editorConfig = frontendConfiguration['Shel.Neos:HyphensEditor'];

initializeRichtextToolbarRegistry(ckEditorRegistry);
initializeConfigRegistry(ckEditorRegistry);
initializeConfigRegistry(ckEditorRegistry, editorConfig);
});
93 changes: 50 additions & 43 deletions Resources/Private/Scripts/HyphensEditor/src/plugins/hyphens.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,70 @@
import {Plugin, ViewRange} from 'ckeditor5-exports';
import ShyCommand from '../commands/shy';
import styles from './hyphens.vanilla-css';
import './hyphens.vanilla-css';

const softHyphenCharacter = '\u00AD';

export default class Hyphens extends Plugin {
static get pluginName() {
return 'Hyphens';
}
function HyphensFactory(config) {
return class Hyphens extends Plugin {
static get pluginName() {
return 'Hyphens';
}

init() {
const {editor} = this;
init() {
const {editor} = this;

editor.commands.add('insertShyEntity', new ShyCommand(this.editor));
editor.commands.add('insertShyEntity', new ShyCommand(this.editor));
if (config.shortcut) {
editor.keystrokes.set(config.shortcut, 'insertShyEntity');
}

editor.conversion.for('editingDowncast').add(dispatcher => {
dispatcher.on('insert:$text', (evt, data, conversionApi) => {
// Here should be an `if` that would check whether the feature's command is enabled.
if (!conversionApi.consumable.consume(data.item, 'insert')) {
return;
}
editor.conversion.for('editingDowncast').add(dispatcher => {
dispatcher.on('insert:$text', (evt, data, conversionApi) => {
// Here should be an `if` that would check whether the feature's command is enabled.
if (!conversionApi.consumable.consume(data.item, 'insert')) {
return;
}

const viewWriter = conversionApi.writer;
const viewWriter = conversionApi.writer;

let modelPosition = data.range.start;
let viewPosition = conversionApi.mapper.toViewPosition(modelPosition);
let modelPosition = data.range.start;
let viewPosition = conversionApi.mapper.toViewPosition(modelPosition);

const dataChunks = data.item.data.split(softHyphenCharacter);
for (let i = 0; i < dataChunks.length; i++) {
const chunk = dataChunks[i];
const dataChunks = data.item.data.split(softHyphenCharacter);
for (let i = 0; i < dataChunks.length; i++) {
const chunk = dataChunks[i];

if (chunk !== '') {
viewWriter.insert(viewPosition, viewWriter.createText(chunk));
if (chunk !== '') {
viewWriter.insert(viewPosition, viewWriter.createText(chunk));

// Need to recalculate `viewPosition` after every inserted item.
modelPosition = modelPosition.getShiftedBy(chunk.length);
viewPosition = conversionApi.mapper.toViewPosition(modelPosition);
}
// Need to recalculate `viewPosition` after every inserted item.
modelPosition = modelPosition.getShiftedBy(chunk.length);
viewPosition = conversionApi.mapper.toViewPosition(modelPosition);
}

// Do not insert anything after the last chunk
if (i === dataChunks.length - 1) {
break;
}
// Do not insert anything after the last chunk
if (i === dataChunks.length - 1) {
break;
}

// Insert utf8 dash character as representation
// We will wrap in in a span in following lines.
viewWriter.insert(viewPosition, viewWriter.createText(softHyphenCharacter));
// Insert utf8 dash character as representation
// We will wrap in in a span in following lines.
viewWriter.insert(viewPosition, viewWriter.createText(softHyphenCharacter));

const viewSpaceSpan = viewWriter.createAttributeElement('span', {class: 'shy'});
const modelWrapRange = new ViewRange(modelPosition, modelPosition.getShiftedBy(1));
const viewWrapRange = conversionApi.mapper.toViewRange(modelWrapRange);
const viewSpaceSpan = viewWriter.createAttributeElement('span', {class: 'shy'});
const modelWrapRange = new ViewRange(modelPosition, modelPosition.getShiftedBy(1));
const viewWrapRange = conversionApi.mapper.toViewRange(modelWrapRange);

viewWriter.wrap(viewWrapRange, viewSpaceSpan);
viewWriter.wrap(viewWrapRange, viewSpaceSpan);

// Need to recalculate `viewPosition` after every inserted item.
modelPosition = modelPosition.getShiftedBy(1);
viewPosition = conversionApi.mapper.toViewPosition(modelPosition);
}
}, {priority: 'high'});
});
// Need to recalculate `viewPosition` after every inserted item.
modelPosition = modelPosition.getShiftedBy(1);
viewPosition = conversionApi.mapper.toViewPosition(modelPosition);
}
}, {priority: 'high'});
});
}
}
}

export default HyphensFactory;

0 comments on commit c542acb

Please sign in to comment.