Skip to content

Commit

Permalink
Add RTL support (codex-team#1248)
Browse files Browse the repository at this point in the history
* [Improvements] ESLint action (codex-team#1099)

* TSLint -> ESLint, GitHub Action

* Update eslint.yml

* Autofix

* more autofix

* fix

* manually fix some issues

* Update CHANGELOG.md

* [Refactor] ESLint fixed (codex-team#1100)

Co-authored-by: Peter Savchenko <[email protected]>

* [Feature] i18n (codex-team#1106)

* i18n first steps

* i18n internal, toolbox, api for tools

* namespaced api

* tn, t

* tn in block tunes

* join toolbox and inlineTools under toolNames

* translations

* make enum toolTypes

* Update block.ts

* Update src/components/core.ts

Co-Authored-By: George Berezhnoy <[email protected]>

* add more types

* rm tn

* export i18n types

* upd bundle

* fix tabulation

* Add type-safe namespaces

* upd

* Improve example

* Update toolbox.ts

* improve examplle

* upd

* fix typo

* Add comments for complex types

Co-authored-by: George Berezhnoy <[email protected]>
Co-authored-by: Georgy Berezhnoy <[email protected]>

* Remove unused submodule

* Fixed: icon centering in Firefox

* Do not load styles twice (codex-team#1112)

* Do not load styles twice

* Add changelog

* Fix issue link

Co-authored-by: Peter Savchenko <[email protected]>

* Show warning if Block to delete is not found (codex-team#1111)

Resolves codex-team#1102

* Save Tools' order in the Toolbox (codex-team#1113)

Resolves codex-team#1073

* fix $.isEmpty performance (codex-team#1096)

* fix $.isEmpty performance

* add changelog

* upd bundle

Co-authored-by: Peter Savchenko <[email protected]>

* Add issue templates (codex-team#1114)

* Update issue templates (codex-team#1121)

* Update issue templates

* Apply suggestions from code review

Co-Authored-By: George Berezhnoy <[email protected]>

* upd texts

* Update feature_request.md

* Update .github/ISSUE_TEMPLATE/discussion.md

Co-Authored-By: George Berezhnoy <[email protected]>

Co-authored-by: George Berezhnoy <[email protected]>

* Allowing deleting block by block id (codex-team#1108)

* Allowing deleting block by block id

* Fixed no argument error

* Making index value optional for delete operation

* Added to changelog

* Making index value optional for delete operation

* Added parameter description

* Update docs/CHANGELOG.md

* Update types/api/blocks.d.ts

* Update editor.js

Co-authored-by: Peter Savchenko <[email protected]>

* Allow navigate next from last non-initial block (codex-team#1110)

Resolves codex-team#1103

* Create CODE_OF_CONDUCT.md (codex-team#1171)

* Create CODE_OF_CONDUCT.md

* Update changelog file

* Update dependencies (codex-team#1122)

* Update dependencies

* upd codex.tooltip

* Update editor.js.LICENSE.txt

Co-authored-by: Peter Savchenko <[email protected]>

* Feature/disable tab event config (codex-team#1164)

* Highlight first block on autofocus (codex-team#1127)

* Fix shortcut for external tools (codex-team#1141)

* fix/shortcut-for-external-tools

* Check inline tools property for shortcut

Co-authored-by: George Berezhnoy <[email protected]>

* Hotfix/issue1133 selection shortcut removed on editor destroy (codex-team#1140)

* Removed shortcut CMD+A on editor destroy codex-team#1133

* Removed patch version and made code cleaner codex-team#1133

* lint error fixes codex-team#1133

Co-authored-by: Sisir <[email protected]>
Co-authored-by: George Berezhnoy <[email protected]>

* [Feature] BlockAPI Interface (codex-team#1075)

* Fix BlockManager.insert method (codex-team#1172)

* Fix BlockManager.insert method

* upd

* Explicitly check for undefined

* Update tools master branches (codex-team#1180)

* Update master branches

* Update image

* Update CHANGELOG.md

* Fix behaviour of inputs editing in block settings (codex-team#1123)

* lint code

* Update CHANGELOG.md

* Added RTL support

* Fixed code style

* Fixed icons positioning in the toolbar in the RTL mode

* Renamed example-dev-rtl.html to example-rtl.html

* Moved 'direction' option to 'i18n' section

* Fixed an issue with arrow navigation between blocks

* Renamed rtl-fix to codex-editor--rtl

* Fixed icons positioning in the narrow mode for RTL

* Replaced 'isRtl' method with getter

* Fixed bug with the editor initialization when 'i18n' option is not set

* narrow mode improved

* Changelog added

Co-authored-by: Peter Savchenko <[email protected]>
Co-authored-by: George Berezhnoy <[email protected]>
Co-authored-by: Georgy Berezhnoy <[email protected]>
Co-authored-by: tasuku-s <[email protected]>
Co-authored-by: Athul Anil Kumar <[email protected]>
Co-authored-by: Taly <[email protected]>
Co-authored-by: flaming-cl <[email protected]>
Co-authored-by: Nguyen Ngoc Son <[email protected]>
Co-authored-by: Sisir Das K <[email protected]>
Co-authored-by: Sisir <[email protected]>
Co-authored-by: ImangazalievM <[email protected]>
  • Loading branch information
12 people committed Aug 27, 2020
1 parent cdb48c4 commit f513fdd
Show file tree
Hide file tree
Showing 13 changed files with 379 additions and 15 deletions.
2 changes: 1 addition & 1 deletion dist/editor.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### 2.19

- `New` - RTL mode added [#670](https://github.com/codex-team/editor.js/issues/670)
- `Fix` — Fix problem with types usage [#1183](https://github.com/codex-team/editor.js/issues/1183)
- `Fix` - Fixed issue with Spam clicking the "Click to tune" button duplicates the icons on FireFox. [#1273](https://github.com/codex-team/editor.js/issues/1273)
- `Fix` - Fixed issue with `editor.blocks.delete(index)` method which throws an error when Editor.js is not focused, even after providing a valid index. [#1182](https://github.com/codex-team/editor.js/issues/1182)
Expand Down
235 changes: 235 additions & 0 deletions example/example-rtl.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
<!--
Use this page for debugging purposes.
Editor Tools are loaded as git-submodules.
You can pull modules by running `yarn pull_tools` and start experimenting.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Editor.js 🤩🧦🤨 example</title>
<link href="https://fonts.googleapis.com/css?family=PT+Mono" rel="stylesheet">
<link href="assets/demo.css" rel="stylesheet">
<script src="assets/json-preview.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
</head>
<body>
<div class="ce-example">
<div class="ce-example__header">
<a class="ce-example__header-logo" href="https://codex.so/editor">Editor.js 🤩🧦🤨</a>

<div class="ce-example__header-menu">
<a href="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/editor-js" target="_blank">Plugins</a>
<a href="https://editorjs.io/usage" target="_blank">Usage</a>
<a href="https://editorjs.io/configuration" target="_blank">Configuration</a>
<a href="https://editorjs.io/creating-a-block-tool" target="_blank">API</a>
</div>
</div>
<div class="ce-example__content _ce-example__content--small">
<div id="editorjs"></div>
<div id="hint" style="text-align: center;">
No submodules found. Run <code class="inline-code">yarn pull_tools</code>
</div>
<div class="ce-example__button" id="saveButton">
editor.save()
</div>
</div>
<div class="ce-example__output">
<pre class="ce-example__output-content" id="output"></pre>

<div class="ce-example__output-footer">
<a href="https://codex.so" style="font-weight: bold;">Made by CodeX</a>
</div>
</div>
</div>

<!-- Load Tools -->
<!--
You can upload Tools to your project's directory and use as in example below.
Also you can load each Tool from CDN or use NPM/Yarn packages.
Read more in Tool's README file. For example:
https://github.com/editor-js/header#installation
-->
<script src="./tools/header/dist/bundle.js" onload="document.getElementById('hint').hidden = true"></script><!-- Header -->
<script src="./tools/simple-image/dist/bundle.js"></script><!-- Image -->
<script src="./tools/delimiter/dist/bundle.js"></script><!-- Delimiter -->
<script src="./tools/list/dist/bundle.js"></script><!-- List -->
<script src="./tools/checklist/dist/bundle.js"></script><!-- Checklist -->
<script src="./tools/quote/dist/bundle.js"></script><!-- Quote -->
<script src="./tools/code/dist/bundle.js"></script><!-- Code -->
<script src="./tools/embed/dist/bundle.js"></script><!-- Embed -->
<script src="./tools/table/dist/bundle.js"></script><!-- Table -->
<script src="./tools/link/dist/bundle.js"></script><!-- Link -->
<script src="./tools/raw/dist/bundle.js"></script><!-- Raw -->
<script src="./tools/warning/dist/bundle.js"></script><!-- Warning -->

<script src="./tools/marker/dist/bundle.js"></script><!-- Marker -->
<script src="./tools/inline-code/dist/bundle.js"></script><!-- Inline Code -->

<!-- Load Editor.js's Core -->
<script src="../dist/editor.js"></script>

<!-- Initialization -->
<script>
/**
* Saving button
*/
const saveButton = document.getElementById('saveButton');

/**
* To initialize the Editor, create a new instance with configuration object
* @see docs/installation.md for mode details
*/
var editor = new EditorJS({
/**
* Wrapper of Editor
*/
holder: 'editorjs',
i18n: {

/**
* Text direction
*/
direction: 'rtl',
},

/**
* Tools list
*/
tools: {
/**
* Each Tool is a Plugin. Pass them via 'class' option with necessary settings {@link docs/tools.md}
*/
header: {
class: Header,
inlineToolbar: ['link'],
config: {
placeholder: 'Header'
},
shortcut: 'CMD+SHIFT+H'
},

/**
* Or pass class directly without any configuration
*/
image: {
class: SimpleImage,
inlineToolbar: ['link'],
},

list: {
class: List,
inlineToolbar: true,
shortcut: 'CMD+SHIFT+L'
},

checklist: {
class: Checklist,
inlineToolbar: true,
},

quote: {
class: Quote,
inlineToolbar: true,
config: {
quotePlaceholder: 'Enter a quote',
captionPlaceholder: 'Quote\'s author',
},
shortcut: 'CMD+SHIFT+O'
},

warning: Warning,

marker: {
class: Marker,
shortcut: 'CMD+SHIFT+M'
},

code: {
class: CodeTool,
shortcut: 'CMD+SHIFT+C'
},

delimiter: Delimiter,

inlineCode: {
class: InlineCode,
shortcut: 'CMD+SHIFT+C'
},

linkTool: LinkTool,

raw: RawTool,

embed: Embed,

table: {
class: Table,
inlineToolbar: true,
shortcut: 'CMD+ALT+T'
},

},

/**
* This Tool will be used as default
*/
// initialBlock: 'paragraph',

/**
* Initial Editor data
*/
data: {
blocks: [
{
type: "header",
data: {
text: "محرر.js",
level: 2
}
},
{
type : 'paragraph',
data : {
text : 'مرحبا! تعرف على المحرر الجديد. في هذه الصفحة ، يمكنك رؤيتها في العمل - حاول تحرير هذا النص.'
}
},
{
type: "header",
data: {
text: "دلائل الميزات",
level: 3
}
},
{
type : 'list',
data : {
items : [
'وهو محرر بنمط الكتلة',
'تقوم بإرجاع إخراج بيانات نظيفة في JSON',
'مصممة لتكون قابلة للتوسيع والتوصيل مع واجهة برمجة تطبيقات بسيطة'
],
style: 'unordered'
}
}
]
},
onReady: function(){
saveButton.click();
},
onChange: function() {
console.log('something changed');
}
});

/**
* Saving example
*/
saveButton.addEventListener('click', function () {
editor.save().then((savedData) => {
cPreview.show(savedData, document.getElementById("output"));
});
});
</script>
</body>
</html>
8 changes: 8 additions & 0 deletions src/components/__module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,12 @@ export default class Module {
public set state(Editor: EditorModules) {
this.Editor = Editor;
}

/**
* Returns true if current direction is RTL (Right-To-Left)
*/
protected get isRtl(): boolean {
return this.config.i18n.direction === 'rtl';
}

}
11 changes: 10 additions & 1 deletion src/components/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,18 @@ export default class Core {
/**
* Adjust i18n
*/
if (config.i18n && config.i18n.messages) {
if (config.i18n?.messages) {
I18n.setDictionary(config.i18n.messages);
}

/**
* Text direction. If not set, uses ltr
*/
if (config.i18n?.direction) {
this.config.i18n = {
direction: config.i18n?.direction || 'ltr',
};
}
}

/**
Expand Down
10 changes: 8 additions & 2 deletions src/components/modules/blockEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,10 @@ export default class BlockEvents extends Module {
return;
}

if (this.Editor.Caret.navigateNext()) {
const navigateNext = event.keyCode === _.keyCodes.UP || (event.keyCode === _.keyCodes.RIGHT && !this.isRtl);
const isNavigated = navigateNext ? this.Editor.Caret.navigateNext() : this.Editor.Caret.navigatePrevious();

if (isNavigated) {
/**
* Default behaviour moves cursor by 1 character, we need to prevent it
*/
Expand Down Expand Up @@ -481,7 +484,10 @@ export default class BlockEvents extends Module {
return;
}

if (this.Editor.Caret.navigatePrevious()) {
const navigatePrevious = event.keyCode === _.keyCodes.UP || (event.keyCode === _.keyCodes.LEFT && !this.isRtl);
const isNavigated = navigatePrevious ? this.Editor.Caret.navigatePrevious() : this.Editor.Caret.navigateNext();

if (isNavigated) {
/**
* Default behaviour moves cursor by 1 character, we need to prevent it
*/
Expand Down
13 changes: 8 additions & 5 deletions src/components/modules/toolbar/conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ export default class ConversionToolbar extends Module {
* Create UI of Conversion Toolbar
*/
public make(): HTMLElement {
this.nodes.wrapper = $.make('div', ConversionToolbar.CSS.conversionToolbarWrapper);
this.nodes.wrapper = $.make('div', [
ConversionToolbar.CSS.conversionToolbarWrapper,
...(this.isRtl ? [this.Editor.UI.CSS.editorRtlFix] : []),
]);
this.nodes.tools = $.make('div', ConversionToolbar.CSS.conversionToolbarTools);

const label = $.make('div', ConversionToolbar.CSS.conversionToolbarLabel, {
Expand Down Expand Up @@ -158,7 +161,7 @@ export default class ConversionToolbar extends Module {
*
* @param {string} replacingToolName - name of Tool which replaces current
*/
public async replaceWithBlock(replacingToolName: string): Promise <void> {
public async replaceWithBlock(replacingToolName: string): Promise<void> {
/**
* At first, we get current Block data
*
Expand Down Expand Up @@ -295,8 +298,8 @@ export default class ConversionToolbar extends Module {
* @param {string} title - button title
*/
private addTool(toolName: string, toolIcon: string, title: string): void {
const tool = $.make('div', [ ConversionToolbar.CSS.conversionTool ]);
const icon = $.make('div', [ ConversionToolbar.CSS.conversionToolIcon ]);
const tool = $.make('div', [ConversionToolbar.CSS.conversionTool]);
const icon = $.make('div', [ConversionToolbar.CSS.conversionToolIcon]);

tool.dataset.tool = toolName;
icon.innerHTML = toolIcon;
Expand All @@ -307,7 +310,7 @@ export default class ConversionToolbar extends Module {
$.append(this.nodes.tools, tool);
this.tools[toolName] = tool;

this.Editor.Listeners.on(tool, 'click', async () => {
this.Editor.Listeners.on(tool, 'click', async() => {
await this.replaceWithBlock(toolName);
});
}
Expand Down
9 changes: 6 additions & 3 deletions src/components/modules/toolbar/inline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class InlineToolbar extends Module {
focusedButton: 'ce-inline-tool--focused',
conversionToggler: 'ce-inline-toolbar__dropdown',
conversionTogglerHidden: 'ce-inline-toolbar__dropdown--hidden',
conversionTogglerContent: 'ce-inline-toolbar__dropdown-content',
conversionTogglerContent: 'ce-inline-toolbar__dropdown-content'
};

/**
Expand Down Expand Up @@ -116,7 +116,10 @@ export default class InlineToolbar extends Module {
* Making DOM
*/
public make(): void {
this.nodes.wrapper = $.make('div', this.CSS.inlineToolbar);
this.nodes.wrapper = $.make('div', [
this.CSS.inlineToolbar,
...(this.isRtl ? [this.Editor.UI.CSS.editorRtlFix] : []),
]);
this.nodes.buttons = $.make('div', this.CSS.buttonsWrapper);
this.nodes.actions = $.make('div', this.CSS.actionsWrapper);

Expand Down Expand Up @@ -569,7 +572,7 @@ export default class InlineToolbar extends Module {

return (toolClass as ToolSettings).class[Tools.INTERNAL_SETTINGS.IS_INLINE];
})
.map(([ name ]: [string, InlineToolConstructable | ToolSettings]) => name);
.map(([name]: [string, InlineToolConstructable | ToolSettings]) => name);

/**
* 1) For internal tools, check public getter 'shortcut'
Expand Down
Loading

0 comments on commit f513fdd

Please sign in to comment.