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 RTL support #1248

Merged
merged 41 commits into from
Aug 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f5e9a66
[Improvements] ESLint action (#1099)
neSpecc Apr 11, 2020
4c0d806
[Refactor] ESLint fixed (#1100)
gohabereg Apr 18, 2020
21cac86
[Feature] i18n (#1106)
neSpecc Apr 20, 2020
775ccbc
Remove unused submodule
tasuku-s Apr 23, 2020
f4c4051
Fixed: icon centering in Firefox
neSpecc Apr 25, 2020
2997ed0
Do not load styles twice (#1112)
gohabereg Apr 25, 2020
4a81699
Show warning if Block to delete is not found (#1111)
gohabereg Apr 25, 2020
7eb642d
Save Tools' order in the Toolbox (#1113)
gohabereg Apr 25, 2020
72213f2
fix $.isEmpty performance (#1096)
tasuku-s Apr 25, 2020
7f876e8
Add issue templates (#1114)
gohabereg Apr 25, 2020
66e70fa
Update issue templates (#1121)
neSpecc Apr 25, 2020
5218a6a
Allowing deleting block by block id (#1108)
athul7744 Apr 25, 2020
ae8591c
Allow navigate next from last non-initial block (#1110)
gohabereg Apr 25, 2020
f6b7b2e
Create CODE_OF_CONDUCT.md (#1171)
talyguryn May 27, 2020
e3410be
Update dependencies (#1122)
gohabereg May 27, 2020
b0ddb10
Feature/disable tab event config (#1164)
flaming-cl May 27, 2020
1eb6d81
Highlight first block on autofocus (#1127)
gohabereg May 27, 2020
5fe8b08
Fix shortcut for external tools (#1141)
sonnn May 27, 2020
7c3bf76
Hotfix/issue1133 selection shortcut removed on editor destroy (#1140)
sis-dk May 27, 2020
ffe5bbc
[Feature] BlockAPI Interface (#1075)
gohabereg May 27, 2020
ff6bd2d
Fix BlockManager.insert method (#1172)
gohabereg Jun 2, 2020
e1500f7
Update tools master branches (#1180)
talyguryn Jun 2, 2020
26b19a3
Fix behaviour of inputs editing in block settings (#1123)
gohabereg Jun 2, 2020
8341c33
Merge branch 'master' into release/2.18
neSpecc Jun 2, 2020
239aaf6
lint code
neSpecc Jun 3, 2020
4cea66f
Update CHANGELOG.md
neSpecc Jun 3, 2020
2714969
Added RTL support
Jul 25, 2020
d8bbfe1
Fixed code style
Jul 25, 2020
d4b6c52
Merge branch 'next' of github.com:codex-team/editor.js into pr/1248
gohabereg Jul 26, 2020
ab4c441
Fixed icons positioning in the toolbar in the RTL mode
Jul 28, 2020
ee1aaec
Merge branch 'rtl-support' of https://github.com/ImangazalievM/editor…
Jul 28, 2020
e4d1957
Renamed example-dev-rtl.html to example-rtl.html
Aug 26, 2020
688fd01
Moved 'direction' option to 'i18n' section
Aug 26, 2020
52b52b4
Fixed an issue with arrow navigation between blocks
Aug 26, 2020
5766b3c
Renamed rtl-fix to codex-editor--rtl
Aug 27, 2020
29dae1c
Fixed icons positioning in the narrow mode for RTL
Aug 27, 2020
4b77289
Replaced 'isRtl' method with getter
Aug 27, 2020
a77fb8d
Fixed bug with the editor initialization when 'i18n' option is not set
Aug 27, 2020
db99084
narrow mode improved
neSpecc Aug 27, 2020
cf99c74
Merge branch 'next' into pr/1248
neSpecc Aug 27, 2020
de127ff
Changelog added
neSpecc Aug 27, 2020
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
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="https://github.com/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