mirror of
https://github.com/Ionaru/easy-markdown-editor
synced 2025-09-24 16:40:55 -06:00
Added multilanguage translation
Signed-off-by: Dmitry Mazurov <dimabzz@gmail.com>
This commit is contained in:
parent
6470e10e29
commit
bf8fc071ea
103
README.md
103
README.md
@ -30,6 +30,7 @@ The editor is entirely customizable, from theming to toolbar buttons and javascr
|
||||
- [Configuration](#configuration)
|
||||
- [Options list](#options-list)
|
||||
- [Options example](#options-example)
|
||||
- [Localization example](#localization-example)
|
||||
- [Toolbar icons](#toolbar-icons)
|
||||
- [Toolbar customization](#toolbar-customization)
|
||||
- [Keyboard shortcuts](#keyboard-shortcuts)
|
||||
@ -115,6 +116,20 @@ easyMDE.value('New input for **EasyMDE**');
|
||||
|
||||
### Options list
|
||||
|
||||
- **locale**: Set locale. Default `en`.
|
||||
- **localization**: Set custom translate.
|
||||
- **imageTexts**: Texts displayed to the user (mainly on the status bar) for the import image feature, where `#image_name#`, `#image_size#` and `#image_max_size#` will replaced by their respective values, that can be used for customization or internationalization:
|
||||
- **sbInit**: Status message displayed initially if `uploadImage` is set to `true`. Defaults to `Attach files by drag and dropping or pasting from clipboard.`.
|
||||
- **sbOnDragEnter**: Status message displayed when the user drags a file to the text area. Defaults to `Drop image to upload it.`.
|
||||
- **sbOnDrop**: Status message displayed when the user drops a file in the text area. Defaults to `Uploading images #images_names#`.
|
||||
- **sbProgress**: Status message displayed to show uploading progress. Defaults to `Uploading #file_name#: #progress#%`.
|
||||
- **sbOnUploaded**: Status message displayed when the image has been uploaded. Defaults to `Uploaded #image_name#`.
|
||||
- **sizeUnits**: A comma-separated list of units used to display messages with human-readable file sizes. Defaults to `b,Kb,Mb`.
|
||||
- **noFileGiven**: The server did not receive any file from the user. Defaults to `You must select a file.`.
|
||||
- **typeNotAllowed**: The user send a file type which doesn't match the `imageAccept` list, or the server returned this error code. Defaults to `This image type is not allowed.`.
|
||||
- **fileTooLarge**: The size of the image being imported is bigger than the `imageMaxSize`, or if the server returned this error code. Defaults to `Image #image_name# is too big (#image_size#).\nMaximum file size is #image_max_size#.`.
|
||||
- **importError**: An unexpected error occurred when uploading the image. Defaults to `Something went wrong when uploading the image #image_name#.`.
|
||||
- **errorMessages**: Errors displayed to the user, using the `errorCallback` option, where `#image_name#`, `#image_size#` and `#image_max_size#` will replaced by their respective values, that can be used for customization or internationalization:
|
||||
- **autoDownloadFontAwesome**: If set to `true`, force downloads Font Awesome (used for icons). If set to `false`, prevents downloading. Defaults to `undefined`, which will intelligently check whether Font Awesome has already been included, then download accordingly.
|
||||
- **autofocus**: If set to `true`, focuses the editor automatically. Defaults to `false`.
|
||||
- **autosave**: *Saves the text that's being written and will load it back in the future. It will forget the text when the form it's contained in is submitted.*
|
||||
@ -123,7 +138,6 @@ easyMDE.value('New input for **EasyMDE**');
|
||||
- **submit_delay**: Delay before assuming that submit of the form failed and saving the text, in milliseconds. Defaults to `autosave.delay` or `10000` (10s).
|
||||
- **uniqueId**: You must set a unique string identifier so that EasyMDE can autosave. Something that separates this from other instances of EasyMDE elsewhere on your website.
|
||||
- **timeFormat**: Set DateTimeFormat. More information see [DateTimeFormat instances](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat). Default `locale: en-US, format: hour:minute`.
|
||||
- **text**: Set text for autosave.
|
||||
- **blockStyles**: Customize how certain buttons that style blocks of text behave.
|
||||
- **bold**: Can be set to `**` or `__`. Defaults to `**`.
|
||||
- **code**: Can be set to ```` ``` ```` or `~~~`. Defaults to ```` ``` ````.
|
||||
@ -149,9 +163,6 @@ easyMDE.value('New input for **EasyMDE**');
|
||||
- **previewClass**: A string or array of strings that will be applied to the preview screen when activated. Defaults to `"editor-preview"`.
|
||||
- **previewRender**: Custom function for parsing the plaintext Markdown and returning HTML. Used when user previews.
|
||||
- **promptURLs**: If set to `true`, a JS alert window appears asking for the link or image URL. Defaults to `false`.
|
||||
- **promptTexts**: Customize the text used to prompt for URLs.
|
||||
- **image**: The text to use when prompting for an image's URL. Defaults to `URL of the image:`.
|
||||
- **link**: The text to use when prompting for a link's URL. Defaults to `URL for the link:`.
|
||||
- **uploadImage**: If set to `true`, enables the image upload functionality, which can be triggered by drag&drop, copy-paste and through the browse-file window (opened when the user click on the *upload-image* icon). Defaults to `false`.
|
||||
- **imageMaxSize**: Maximum image size in bytes, checked before upload (note: never trust client, always check image size at server-side). Defaults to `1024*1024*2` (2Mb).
|
||||
- **imageAccept**: A comma-separated list of mime-types used to check image type before upload (note: never trust client, always check file types at server-side). Defaults to `image/png, image/jpeg`.
|
||||
@ -162,18 +173,6 @@ easyMDE.value('New input for **EasyMDE**');
|
||||
- otherwise: `{"error": "<errorCode>"}`, where *errorCode* can be `noFileGiven` (HTTP 400), `typeNotAllowed` (HTTP 415), `fileTooLarge` (HTTP 413) or `importError` (see *errorMessages* below). If *errorCode* is not one of the *errorMessages*, it is alerted unchanged to the user. This allows for server side error messages.
|
||||
No default value.
|
||||
- **imageCSRFToken**: CSRF token to include with AJAX call to upload image. For instance used with Django backend.
|
||||
- **imageTexts**: Texts displayed to the user (mainly on the status bar) for the import image feature, where `#image_name#`, `#image_size#` and `#image_max_size#` will replaced by their respective values, that can be used for customization or internationalization:
|
||||
- **sbInit**: Status message displayed initially if `uploadImage` is set to `true`. Defaults to `Attach files by drag and dropping or pasting from clipboard.`.
|
||||
- **sbOnDragEnter**: Status message displayed when the user drags a file to the text area. Defaults to `Drop image to upload it.`.
|
||||
- **sbOnDrop**: Status message displayed when the user drops a file in the text area. Defaults to `Uploading images #images_names#`.
|
||||
- **sbProgress**: Status message displayed to show uploading progress. Defaults to `Uploading #file_name#: #progress#%`.
|
||||
- **sbOnUploaded**: Status message displayed when the image has been uploaded. Defaults to `Uploaded #image_name#`.
|
||||
- **sizeUnits**: A comma-separated list of units used to display messages with human-readable file sizes. Defaults to `b,Kb,Mb`.
|
||||
- **errorMessages**: Errors displayed to the user, using the `errorCallback` option, where `#image_name#`, `#image_size#` and `#image_max_size#` will replaced by their respective values, that can be used for customization or internationalization:
|
||||
- **noFileGiven**: The server did not receive any file from the user. Defaults to `You must select a file.`.
|
||||
- **typeNotAllowed**: The user send a file type which doesn't match the `imageAccept` list, or the server returned this error code. Defaults to `This image type is not allowed.`.
|
||||
- **fileTooLarge**: The size of the image being imported is bigger than the `imageMaxSize`, or if the server returned this error code. Defaults to `Image #image_name# is too big (#image_size#).\nMaximum file size is #image_max_size#.`.
|
||||
- **importError**: An unexpected error occurred when uploading the image. Defaults to `Something went wrong when uploading the image #image_name#.`.
|
||||
- **errorCallback**: A callback function used to define how to display an error message. Defaults to `function(errorMessage) {alert(errorMessage);};`.
|
||||
- **renderingConfig**: Adjust settings for parsing the Markdown during previewing (not editing).
|
||||
- **codeSyntaxHighlighting**: If set to `true`, will highlight using [highlight.js](https://github.com/isagalaev/highlight.js). Defaults to `false`. To use this feature you must include highlight.js on your page or pass in using the `hljs` option. For example, include the script and the CSS files like:<br>`<script src="https://cdn.jsdelivr.net/highlight.js/latest/highlight.min.js"></script>`<br>`<link rel="stylesheet" href="https://cdn.jsdelivr.net/highlight.js/latest/styles/github.min.css">`
|
||||
@ -202,6 +201,14 @@ Most options demonstrate the non-default behavior:
|
||||
|
||||
```JavaScript
|
||||
var editor = new EasyMDE({
|
||||
locale: 'en',
|
||||
localization: {
|
||||
"status": {
|
||||
"lines": "lines",
|
||||
"words": "words",
|
||||
"autosave": "Autosaved: ",
|
||||
},
|
||||
},
|
||||
autofocus: true,
|
||||
autosave: {
|
||||
enabled: true,
|
||||
@ -218,7 +225,6 @@ var editor = new EasyMDE({
|
||||
minute: '2-digit',
|
||||
},
|
||||
},
|
||||
text: "Autosaved: "
|
||||
},
|
||||
blockStyles: {
|
||||
bold: "__",
|
||||
@ -258,10 +264,6 @@ var editor = new EasyMDE({
|
||||
return "Loading...";
|
||||
},
|
||||
promptURLs: true,
|
||||
promptTexts: {
|
||||
image: "Custom prompt for URL:",
|
||||
link: "Custom prompt for URL:",
|
||||
},
|
||||
renderingConfig: {
|
||||
singleLineBreaks: false,
|
||||
codeSyntaxHighlighting: true,
|
||||
@ -294,7 +296,66 @@ var editor = new EasyMDE({
|
||||
toolbarTips: false,
|
||||
});
|
||||
```
|
||||
### Localization example
|
||||
|
||||
```JavaScript
|
||||
var editor = new EasyMDE({
|
||||
locale: 'en',
|
||||
localization: {
|
||||
"promptTexts": {
|
||||
"link": "URL for the link:",
|
||||
"image": "URL of the image:"
|
||||
},
|
||||
"status": {
|
||||
"lines": "lines",
|
||||
"words": "words",
|
||||
"autosave": "Autosaved: "
|
||||
},
|
||||
"errorMessages": {
|
||||
"noFileGiven": "You must select a file.",
|
||||
"typeNotAllowed": "This image type is not allowed.",
|
||||
"fileTooLarge": "Image #image_name# is too big (#image_size#).\nMaximum file size is #image_max_size#.",
|
||||
"importError": "Something went wrong when uploading the image #image_name#."
|
||||
},
|
||||
"imageTexts": {
|
||||
"sbInit": "Attach files by drag and dropping or pasting from clipboard.",
|
||||
"sbOnDragEnter": "Drop image to upload it.",
|
||||
"sbOnDrop": "Uploading image #images_names#...",
|
||||
"sbProgress": "Uploading #file_name#: #progress#%",
|
||||
"sbOnUploaded": "Uploaded #image_name#",
|
||||
"sizeUnits": "b,Kb,Mb"
|
||||
},
|
||||
"toolbar": {
|
||||
"bold": {"title": "Bold"},
|
||||
"italic": {"title": "Italic"},
|
||||
"strikethrough": {"title": "Strikethrough"},
|
||||
"heading": {"title": "Heading"},
|
||||
"heading-smaller": {"title": "Smaller Heading"},
|
||||
"heading-bigger": {"title": "Bigger Heading"},
|
||||
"heading-1": {"title": "Big Heading"},
|
||||
"heading-2": {"title": "Medium Heading"},
|
||||
"heading-3": {"title": "Small Heading"},
|
||||
"code": {"title": "Code"},
|
||||
"quote": {"title": "Quote"},
|
||||
"unordered-list": {"title": "Generic List"},
|
||||
"ordered-list": {"title": "Numbered List"},
|
||||
"clean-block": {"title": "Clean block"},
|
||||
"link": {"title": "Create Link"},
|
||||
"image": {"title": "Insert Image"},
|
||||
"upload-image": {"title": "Import an image"},
|
||||
"table": {"title": "Insert Table"},
|
||||
"horizontal-rule": {"title": "Insert Horizontal Line"},
|
||||
"preview": {"title": "Toggle Preview"},
|
||||
"side-by-side": {"title": "Toggle Side by Side"},
|
||||
"fullscreen": {"title": "Toggle Fullscreen"},
|
||||
"guide": {"title": "Markdown Guide"},
|
||||
"undo": {"title": "Undo"},
|
||||
"redo": {"title": "Redo"}
|
||||
}
|
||||
},
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
### Toolbar icons
|
||||
|
||||
|
@ -205,12 +205,12 @@
|
||||
content: 'lines: '
|
||||
}
|
||||
|
||||
.editor-statusbar .words:before {
|
||||
content: 'words: '
|
||||
.editor-statusbar .lines:before {
|
||||
content: attr(data-status-bar-before) ': ';
|
||||
}
|
||||
|
||||
.editor-statusbar .characters:before {
|
||||
content: 'characters: '
|
||||
.editor-statusbar .words:before {
|
||||
content: attr(data-status-bar-before) ': ';
|
||||
}
|
||||
|
||||
.editor-preview-full {
|
||||
|
@ -11,7 +11,8 @@ require('codemirror/addon/search/searchcursor.js');
|
||||
require('codemirror/mode/gfm/gfm.js');
|
||||
require('codemirror/mode/xml/xml.js');
|
||||
var CodeMirrorSpellChecker = require('codemirror-spell-checker');
|
||||
var marked = require('marked/lib/marked');
|
||||
var marked = require('marked');
|
||||
var localization = require('./languages.json');
|
||||
|
||||
|
||||
// Some variables
|
||||
@ -730,7 +731,7 @@ function drawLink(editor) {
|
||||
var options = editor.options;
|
||||
var url = 'https://';
|
||||
if (options.promptURLs) {
|
||||
url = prompt(options.promptTexts.link, 'https://');
|
||||
url = prompt(options.locale.promptTexts.link, 'https://');
|
||||
if (!url) {
|
||||
return false;
|
||||
}
|
||||
@ -747,7 +748,7 @@ function drawImage(editor) {
|
||||
var options = editor.options;
|
||||
var url = 'https://';
|
||||
if (options.promptURLs) {
|
||||
url = prompt(options.promptTexts.image, 'https://');
|
||||
url = prompt(options.locale.promptTexts.image, 'https://');
|
||||
if (!url) {
|
||||
return false;
|
||||
}
|
||||
@ -776,9 +777,9 @@ function afterImageUploaded(editor, url) {
|
||||
var imageName = url.substr(url.lastIndexOf('/') + 1);
|
||||
_replaceSelection(cm, stat.image, options.insertTexts.uploadedImage, url);
|
||||
// show uploaded image filename for 1000ms
|
||||
editor.updateStatusBar('upload-image', editor.options.imageTexts.sbOnUploaded.replace('#image_name#', imageName));
|
||||
editor.updateStatusBar('upload-image', editor.options.locale.imageTexts.sbOnUploaded.replace('#image_name#', imageName));
|
||||
setTimeout(function () {
|
||||
editor.updateStatusBar('upload-image', editor.options.imageTexts.sbInit);
|
||||
editor.updateStatusBar('upload-image', editor.options.locale.imageTexts.sbInit);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@ -1292,58 +1293,49 @@ var toolbarBuiltInButtons = {
|
||||
name: 'bold',
|
||||
action: toggleBold,
|
||||
className: 'fa fa-bold',
|
||||
title: 'Bold',
|
||||
default: true,
|
||||
},
|
||||
'italic': {
|
||||
name: 'italic',
|
||||
action: toggleItalic,
|
||||
className: 'fa fa-italic',
|
||||
title: 'Italic',
|
||||
default: true,
|
||||
},
|
||||
'strikethrough': {
|
||||
name: 'strikethrough',
|
||||
action: toggleStrikethrough,
|
||||
className: 'fa fa-strikethrough',
|
||||
title: 'Strikethrough',
|
||||
},
|
||||
'heading': {
|
||||
name: 'heading',
|
||||
action: toggleHeadingSmaller,
|
||||
className: 'fa fa-header fa-heading',
|
||||
title: 'Heading',
|
||||
default: true,
|
||||
},
|
||||
'heading-smaller': {
|
||||
name: 'heading-smaller',
|
||||
action: toggleHeadingSmaller,
|
||||
className: 'fa fa-header fa-heading header-smaller',
|
||||
title: 'Smaller Heading',
|
||||
},
|
||||
'heading-bigger': {
|
||||
name: 'heading-bigger',
|
||||
action: toggleHeadingBigger,
|
||||
className: 'fa fa-header fa-heading header-bigger',
|
||||
title: 'Bigger Heading',
|
||||
},
|
||||
'heading-1': {
|
||||
name: 'heading-1',
|
||||
action: toggleHeading1,
|
||||
className: 'fa fa-header fa-heading header-1',
|
||||
title: 'Big Heading',
|
||||
},
|
||||
'heading-2': {
|
||||
name: 'heading-2',
|
||||
action: toggleHeading2,
|
||||
className: 'fa fa-header fa-heading header-2',
|
||||
title: 'Medium Heading',
|
||||
},
|
||||
'heading-3': {
|
||||
name: 'heading-3',
|
||||
action: toggleHeading3,
|
||||
className: 'fa fa-header fa-heading header-3',
|
||||
title: 'Small Heading',
|
||||
},
|
||||
'separator-1': {
|
||||
name: 'separator-1',
|
||||
@ -1352,34 +1344,29 @@ var toolbarBuiltInButtons = {
|
||||
name: 'code',
|
||||
action: toggleCodeBlock,
|
||||
className: 'fa fa-code',
|
||||
title: 'Code',
|
||||
},
|
||||
'quote': {
|
||||
name: 'quote',
|
||||
action: toggleBlockquote,
|
||||
className: 'fa fa-quote-left',
|
||||
title: 'Quote',
|
||||
default: true,
|
||||
},
|
||||
'unordered-list': {
|
||||
name: 'unordered-list',
|
||||
action: toggleUnorderedList,
|
||||
className: 'fa fa-list-ul',
|
||||
title: 'Generic List',
|
||||
default: true,
|
||||
},
|
||||
'ordered-list': {
|
||||
name: 'ordered-list',
|
||||
action: toggleOrderedList,
|
||||
className: 'fa fa-list-ol',
|
||||
title: 'Numbered List',
|
||||
default: true,
|
||||
},
|
||||
'clean-block': {
|
||||
name: 'clean-block',
|
||||
action: cleanBlock,
|
||||
className: 'fa fa-eraser',
|
||||
title: 'Clean block',
|
||||
},
|
||||
'separator-2': {
|
||||
name: 'separator-2',
|
||||
@ -1388,33 +1375,28 @@ var toolbarBuiltInButtons = {
|
||||
name: 'link',
|
||||
action: drawLink,
|
||||
className: 'fa fa-link',
|
||||
title: 'Create Link',
|
||||
default: true,
|
||||
},
|
||||
'image': {
|
||||
name: 'image',
|
||||
action: drawImage,
|
||||
className: 'fa fa-image',
|
||||
title: 'Insert Image',
|
||||
default: true,
|
||||
},
|
||||
'upload-image': {
|
||||
name: 'upload-image',
|
||||
action: drawUploadedImage,
|
||||
className: 'fa fa-image',
|
||||
title: 'Import an image',
|
||||
},
|
||||
'table': {
|
||||
name: 'table',
|
||||
action: drawTable,
|
||||
className: 'fa fa-table',
|
||||
title: 'Insert Table',
|
||||
},
|
||||
'horizontal-rule': {
|
||||
name: 'horizontal-rule',
|
||||
action: drawHorizontalRule,
|
||||
className: 'fa fa-minus',
|
||||
title: 'Insert Horizontal Line',
|
||||
},
|
||||
'separator-3': {
|
||||
name: 'separator-3',
|
||||
@ -1424,7 +1406,6 @@ var toolbarBuiltInButtons = {
|
||||
action: togglePreview,
|
||||
className: 'fa fa-eye',
|
||||
noDisable: true,
|
||||
title: 'Toggle Preview',
|
||||
default: true,
|
||||
},
|
||||
'side-by-side': {
|
||||
@ -1433,7 +1414,6 @@ var toolbarBuiltInButtons = {
|
||||
className: 'fa fa-columns',
|
||||
noDisable: true,
|
||||
noMobile: true,
|
||||
title: 'Toggle Side by Side',
|
||||
default: true,
|
||||
},
|
||||
'fullscreen': {
|
||||
@ -1442,7 +1422,6 @@ var toolbarBuiltInButtons = {
|
||||
className: 'fa fa-arrows-alt',
|
||||
noDisable: true,
|
||||
noMobile: true,
|
||||
title: 'Toggle Fullscreen',
|
||||
default: true,
|
||||
},
|
||||
'separator-4': {
|
||||
@ -1453,7 +1432,6 @@ var toolbarBuiltInButtons = {
|
||||
action: 'https://www.markdownguide.org/basic-syntax/',
|
||||
className: 'fa fa-question-circle',
|
||||
noDisable: true,
|
||||
title: 'Markdown Guide',
|
||||
default: true,
|
||||
},
|
||||
'separator-5': {
|
||||
@ -1464,14 +1442,12 @@ var toolbarBuiltInButtons = {
|
||||
action: undo,
|
||||
className: 'fa fa-undo',
|
||||
noDisable: true,
|
||||
title: 'Undo',
|
||||
},
|
||||
'redo': {
|
||||
name: 'redo',
|
||||
action: redo,
|
||||
className: 'fa fa-repeat fa-redo',
|
||||
noDisable: true,
|
||||
title: 'Redo',
|
||||
},
|
||||
};
|
||||
|
||||
@ -1484,11 +1460,6 @@ var insertTexts = {
|
||||
horizontalRule: ['', '\n\n-----\n\n'],
|
||||
};
|
||||
|
||||
var promptTexts = {
|
||||
link: 'URL for the link:',
|
||||
image: 'URL of the image:',
|
||||
};
|
||||
|
||||
var timeFormat = {
|
||||
locale: 'en-US',
|
||||
format: {
|
||||
@ -1503,31 +1474,6 @@ var blockStyles = {
|
||||
'italic': '*',
|
||||
};
|
||||
|
||||
/**
|
||||
* Texts displayed to the user (mainly on the status bar) for the import image
|
||||
* feature. Can be used for customization or internationalization.
|
||||
*/
|
||||
var imageTexts = {
|
||||
sbInit: 'Attach files by drag and dropping or pasting from clipboard.',
|
||||
sbOnDragEnter: 'Drop image to upload it.',
|
||||
sbOnDrop: 'Uploading image #images_names#...',
|
||||
sbProgress: 'Uploading #file_name#: #progress#%',
|
||||
sbOnUploaded: 'Uploaded #image_name#',
|
||||
sizeUnits: 'b,Kb,Mb',
|
||||
};
|
||||
|
||||
/**
|
||||
* Errors displayed to the user, using the `errorCallback` option. Can be used for
|
||||
* customization or internationalization.
|
||||
*/
|
||||
var errorMessages = {
|
||||
noFileGiven: 'You must select a file.',
|
||||
typeNotAllowed: 'This image type is not allowed.',
|
||||
fileTooLarge: 'Image #image_name# is too big (#image_size#).\n' +
|
||||
'Maximum file size is #image_max_size#.',
|
||||
importError: 'Something went wrong when uploading the image #image_name#.',
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface of EasyMDE.
|
||||
*/
|
||||
@ -1625,24 +1571,22 @@ function EasyMDE(options) {
|
||||
}, options.parsingConfig || {});
|
||||
|
||||
|
||||
// Merging the insertTexts, with the given options
|
||||
// Merging localizations
|
||||
options.locale = extend(localization['en'], localization[options.locale], options.localization || {});
|
||||
|
||||
options.insertTexts = extend({}, insertTexts, options.insertTexts || {});
|
||||
|
||||
|
||||
// Merging the promptTexts, with the given options
|
||||
options.promptTexts = extend({}, promptTexts, options.promptTexts || {});
|
||||
|
||||
|
||||
// Merging the blockStyles, with the given options
|
||||
options.blockStyles = extend({}, blockStyles, options.blockStyles || {});
|
||||
|
||||
|
||||
if (options.autosave != undefined) {
|
||||
// Merging the Autosave timeFormat, with the given options
|
||||
options.autosave.timeFormat = extend({}, timeFormat, options.autosave.timeFormat || {});
|
||||
}
|
||||
|
||||
|
||||
// Merging the blockStyles, with the given options
|
||||
options.blockStyles = extend({}, blockStyles, options.blockStyles || {});
|
||||
|
||||
|
||||
// Merging the shortcuts, with the given options
|
||||
options.shortcuts = extend({}, shortcuts, options.shortcuts || {});
|
||||
|
||||
@ -1656,8 +1600,6 @@ function EasyMDE(options) {
|
||||
options.uploadImage = options.uploadImage || false;
|
||||
options.imageMaxSize = options.imageMaxSize || 2097152; // 1024 * 1024 * 2
|
||||
options.imageAccept = options.imageAccept || 'image/png, image/jpeg';
|
||||
options.imageTexts = extend({}, imageTexts, options.imageTexts || {});
|
||||
options.errorMessages = extend({}, errorMessages, options.errorMessages || {});
|
||||
|
||||
|
||||
// Change unique_id to uniqueId for backwards compatibility
|
||||
@ -1684,23 +1626,23 @@ function EasyMDE(options) {
|
||||
var self = this;
|
||||
|
||||
this.codemirror.on('dragenter', function (cm, event) {
|
||||
self.updateStatusBar('upload-image', self.options.imageTexts.sbOnDragEnter);
|
||||
self.updateStatusBar('upload-image', self.options.locale.imageTexts.sbOnDragEnter);
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
this.codemirror.on('dragend', function (cm, event) {
|
||||
self.updateStatusBar('upload-image', self.options.imageTexts.sbInit);
|
||||
self.updateStatusBar('upload-image', self.options.locale.imageTexts.sbInit);
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
this.codemirror.on('dragleave', function (cm, event) {
|
||||
self.updateStatusBar('upload-image', self.options.imageTexts.sbInit);
|
||||
self.updateStatusBar('upload-image', self.options.locale.imageTexts.sbInit);
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
this.codemirror.on('dragover', function (cm, event) {
|
||||
self.updateStatusBar('upload-image', self.options.imageTexts.sbOnDragEnter);
|
||||
self.updateStatusBar('upload-image', self.options.locale.imageTexts.sbOnDragEnter);
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
@ -1745,7 +1687,7 @@ EasyMDE.prototype.uploadImages = function (files, onSuccess, onError) {
|
||||
names.push(files[i].name);
|
||||
this.uploadImage(files[i], onSuccess, onError);
|
||||
}
|
||||
this.updateStatusBar('upload-image', this.options.imageTexts.sbOnDrop.replace('#images_names#', names.join(', ')));
|
||||
this.updateStatusBar('upload-image', this.options.locale.imageTexts.sbOnDrop.replace('#images_names#', names.join(', ')));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1767,7 +1709,7 @@ EasyMDE.prototype.uploadImagesUsingCustomFunction = function (imageUploadFunctio
|
||||
names.push(files[i].name);
|
||||
this.uploadImageUsingCustomFunction(imageUploadFunction, files[i]);
|
||||
}
|
||||
this.updateStatusBar('upload-image', this.options.imageTexts.sbOnDrop.replace('#images_names#', names.join(', ')));
|
||||
this.updateStatusBar('upload-image', this.options.locale.imageTexts.sbOnDrop.replace('#images_names#', names.join(', ')));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2025,7 +1967,7 @@ EasyMDE.prototype.autosave = function () {
|
||||
if (el != null && el != undefined && el != '') {
|
||||
var d = new Date();
|
||||
var dd = new Intl.DateTimeFormat([this.options.autosave.timeFormat.locale, 'en-US'], this.options.autosave.timeFormat.format).format(d);
|
||||
var save = this.options.autosave.text == undefined ? 'Autosaved: ' : this.options.autosave.text;
|
||||
var save = this.options.locale.status.autosave;
|
||||
|
||||
el.innerHTML = save + dd;
|
||||
}
|
||||
@ -2092,7 +2034,7 @@ EasyMDE.prototype.uploadImage = function (file, onSuccess, onError) {
|
||||
self.updateStatusBar('upload-image', errorMessage);
|
||||
|
||||
setTimeout(function () {
|
||||
self.updateStatusBar('upload-image', self.options.imageTexts.sbInit);
|
||||
self.updateStatusBar('upload-image', self.options.locale.imageTexts.sbInit);
|
||||
}, 10000);
|
||||
|
||||
// run custom error handler
|
||||
@ -2104,7 +2046,7 @@ EasyMDE.prototype.uploadImage = function (file, onSuccess, onError) {
|
||||
}
|
||||
|
||||
function fillErrorMessage(errorMessage) {
|
||||
var units = self.options.imageTexts.sizeUnits.split(',');
|
||||
var units = self.options.locale.imageTexts.sizeUnits.split(',');
|
||||
return errorMessage
|
||||
.replace('#image_name#', file.name)
|
||||
.replace('#image_size#', humanFileSize(file.size, units))
|
||||
@ -2112,7 +2054,7 @@ EasyMDE.prototype.uploadImage = function (file, onSuccess, onError) {
|
||||
}
|
||||
|
||||
if (file.size > this.options.imageMaxSize) {
|
||||
onErrorSup(fillErrorMessage(this.options.errorMessages.fileTooLarge));
|
||||
onErrorSup(fillErrorMessage(this.options.locale.errorMessages.fileTooLarge));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2127,7 +2069,7 @@ EasyMDE.prototype.uploadImage = function (file, onSuccess, onError) {
|
||||
request.upload.onprogress = function (event) {
|
||||
if (event.lengthComputable) {
|
||||
var progress = '' + Math.round((event.loaded * 100) / event.total);
|
||||
self.updateStatusBar('upload-image', self.options.imageTexts.sbProgress.replace('#file_name#', file.name).replace('#progress#', progress));
|
||||
self.updateStatusBar('upload-image', self.options.locale.imageTexts.sbProgress.replace('#file_name#', file.name).replace('#progress#', progress));
|
||||
}
|
||||
};
|
||||
request.open('POST', this.options.imageUploadEndpoint);
|
||||
@ -2137,20 +2079,20 @@ EasyMDE.prototype.uploadImage = function (file, onSuccess, onError) {
|
||||
var response = JSON.parse(this.responseText);
|
||||
} catch (error) {
|
||||
console.error('EasyMDE: The server did not return a valid json.');
|
||||
onErrorSup(fillErrorMessage(self.options.errorMessages.importError));
|
||||
onErrorSup(fillErrorMessage(self.options.locale.errorMessages.importError));
|
||||
return;
|
||||
}
|
||||
if (this.status === 200 && response && !response.error && response.data && response.data.filePath) {
|
||||
onSuccess(window.location.origin + '/' + response.data.filePath);
|
||||
} else {
|
||||
if (response.error && response.error in self.options.errorMessages) { // preformatted error message
|
||||
onErrorSup(fillErrorMessage(self.options.errorMessages[response.error]));
|
||||
if (response.error && response.error in self.options.locale.errorMessages) { // preformatted error message
|
||||
onErrorSup(fillErrorMessage(self.options.locale.errorMessages[response.error]));
|
||||
} else if (response.error) { // server side generated error message
|
||||
onErrorSup(fillErrorMessage(response.error));
|
||||
} else { //unknown error
|
||||
console.error('EasyMDE: Received an unexpected response after uploading the image.'
|
||||
+ this.status + ' (' + this.statusText + ')');
|
||||
onErrorSup(fillErrorMessage(self.options.errorMessages.importError));
|
||||
onErrorSup(fillErrorMessage(self.options.locale.errorMessages.importError));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -2158,7 +2100,7 @@ EasyMDE.prototype.uploadImage = function (file, onSuccess, onError) {
|
||||
request.onerror = function (event) {
|
||||
console.error('EasyMDE: An unexpected error occurred when trying to upload the image.'
|
||||
+ event.target.status + ' (' + event.target.statusText + ')');
|
||||
onErrorSup(self.options.errorMessages.importError);
|
||||
onErrorSup(self.options.locale.errorMessages.importError);
|
||||
};
|
||||
|
||||
request.send(formData);
|
||||
@ -2183,7 +2125,7 @@ EasyMDE.prototype.uploadImageUsingCustomFunction = function(imageUploadFunction,
|
||||
self.updateStatusBar('upload-image', filledErrorMessage);
|
||||
|
||||
setTimeout(function () {
|
||||
self.updateStatusBar('upload-image', self.options.imageTexts.sbInit);
|
||||
self.updateStatusBar('upload-image', self.options.locale.imageTexts.sbInit);
|
||||
}, 10000);
|
||||
|
||||
// run error handler from options, this alerts the message.
|
||||
@ -2191,7 +2133,7 @@ EasyMDE.prototype.uploadImageUsingCustomFunction = function(imageUploadFunction,
|
||||
}
|
||||
|
||||
function fillErrorMessage(errorMessage) {
|
||||
var units = self.options.imageTexts.sizeUnits.split(',');
|
||||
var units = self.options.locale.imageTexts.sizeUnits.split(',');
|
||||
return errorMessage
|
||||
.replace('#image_name#', file.name)
|
||||
.replace('#image_size#', humanFileSize(file.size, units))
|
||||
@ -2265,7 +2207,7 @@ EasyMDE.prototype.createToolbar = function (items) {
|
||||
var i;
|
||||
for (i = 0; i < items.length; i++) {
|
||||
if (toolbarBuiltInButtons[items[i]] != undefined) {
|
||||
items[i] = toolbarBuiltInButtons[items[i]];
|
||||
items[i] = extend({}, toolbarBuiltInButtons[items[i]], this.options.locale.toolbar[items[i]] || {});
|
||||
}
|
||||
}
|
||||
|
||||
@ -2372,25 +2314,30 @@ EasyMDE.prototype.createStatusbar = function (status) {
|
||||
|
||||
// Set up the built-in items
|
||||
var items = [];
|
||||
var i, onUpdate, defaultValue;
|
||||
var i, onUpdate, onCursorActivity, defaultValue, dataSet;
|
||||
|
||||
for (i = 0; i < status.length; i++) {
|
||||
// Reset some values
|
||||
onUpdate = undefined;
|
||||
onCursorActivity = undefined;
|
||||
defaultValue = undefined;
|
||||
|
||||
dataSet = undefined;
|
||||
|
||||
// Handle if custom or not
|
||||
if (typeof status[i] === 'object') {
|
||||
items.push({
|
||||
className: status[i].className,
|
||||
dataSet: status[i].dataSet,
|
||||
defaultValue: status[i].defaultValue,
|
||||
onUpdate: status[i].onUpdate,
|
||||
onCursorActivity: status[i].onCursorActivity,
|
||||
});
|
||||
} else {
|
||||
var name = status[i];
|
||||
|
||||
if (name === 'words') {
|
||||
dataSet = options.locale.status[name];
|
||||
|
||||
defaultValue = function (el) {
|
||||
el.innerHTML = wordCount(cm.getValue());
|
||||
};
|
||||
@ -2398,6 +2345,8 @@ EasyMDE.prototype.createStatusbar = function (status) {
|
||||
el.innerHTML = wordCount(cm.getValue());
|
||||
};
|
||||
} else if (name === 'lines') {
|
||||
dataSet = options.locale.status[name];
|
||||
|
||||
defaultValue = function (el) {
|
||||
el.innerHTML = cm.lineCount();
|
||||
};
|
||||
@ -2410,6 +2359,12 @@ EasyMDE.prototype.createStatusbar = function (status) {
|
||||
};
|
||||
onUpdate = function (el) {
|
||||
var pos = cm.getCursor();
|
||||
|
||||
el.innerHTML = pos.line + ':' + pos.ch;
|
||||
};
|
||||
onCursorActivity = function (el) {
|
||||
var pos = cm.getCursor();
|
||||
|
||||
el.innerHTML = pos.line + ':' + pos.ch;
|
||||
};
|
||||
} else if (name === 'autosave') {
|
||||
@ -2420,14 +2375,16 @@ EasyMDE.prototype.createStatusbar = function (status) {
|
||||
};
|
||||
} else if (name === 'upload-image') {
|
||||
defaultValue = function (el) {
|
||||
el.innerHTML = options.imageTexts.sbInit;
|
||||
el.innerHTML = options.locale.imageTexts.sbInit;
|
||||
};
|
||||
}
|
||||
|
||||
items.push({
|
||||
className: name,
|
||||
dataSet: dataSet,
|
||||
defaultValue: defaultValue,
|
||||
onUpdate: onUpdate,
|
||||
onCursorActivity: onCursorActivity,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -2448,6 +2405,10 @@ EasyMDE.prototype.createStatusbar = function (status) {
|
||||
var el = document.createElement('span');
|
||||
el.className = item.className;
|
||||
|
||||
if (item.dataSet != undefined) {
|
||||
el.dataset.statusBarBefore = item.dataSet;
|
||||
}
|
||||
|
||||
|
||||
// Ensure the defaultValue is a function
|
||||
if (typeof item.defaultValue === 'function') {
|
||||
@ -2465,6 +2426,15 @@ EasyMDE.prototype.createStatusbar = function (status) {
|
||||
}(el, item)));
|
||||
}
|
||||
|
||||
// Ensure the onCursorActivity is a function
|
||||
if (typeof item.onCursorActivity === 'function') {
|
||||
// Create a closure around the span of the current action, then execute the onCursorActivity handler
|
||||
this.codemirror.on('cursorActivity', (function (el, item) {
|
||||
return function () {
|
||||
item.onCursorActivity(el);
|
||||
};
|
||||
}(el, item)));
|
||||
}
|
||||
|
||||
// Append the item to the status bar
|
||||
bar.appendChild(el);
|
||||
|
66
src/js/languages.json
Normal file
66
src/js/languages.json
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
{
|
||||
"en": {
|
||||
"promptTexts": {
|
||||
"link": "URL for the link:",
|
||||
"image": "URL of the image:"
|
||||
},
|
||||
"status": {
|
||||
"lines": "lines",
|
||||
"words": "words",
|
||||
"autosave": "Autosaved: "
|
||||
},
|
||||
"errorMessages": {
|
||||
"noFileGiven": "You must select a file.",
|
||||
"typeNotAllowed": "This image type is not allowed.",
|
||||
"fileTooLarge": "Image #image_name# is too big (#image_size#).\nMaximum file size is #image_max_size#.",
|
||||
"importError": "Something went wrong when uploading the image #image_name#."
|
||||
},
|
||||
"imageTexts": {
|
||||
"sbInit": "Attach files by drag and dropping or pasting from clipboard.",
|
||||
"sbOnDragEnter": "Drop image to upload it.",
|
||||
"sbOnDrop": "Uploading image #images_names#...",
|
||||
"sbProgress": "Uploading #file_name#: #progress#%",
|
||||
"sbOnUploaded": "Uploaded #image_name#",
|
||||
"sizeUnits": "b,Kb,Mb"
|
||||
},
|
||||
"toolbar": {
|
||||
"bold": {"title": "Bold"},
|
||||
"italic": {"title": "Italic"},
|
||||
"strikethrough": {"title": "Strikethrough"},
|
||||
"heading": {"title": "Heading"},
|
||||
"heading-smaller": {"title": "Smaller Heading"},
|
||||
"heading-bigger": {"title": "Bigger Heading"},
|
||||
"heading-1": {"title": "Big Heading"},
|
||||
"heading-2": {"title": "Medium Heading"},
|
||||
"heading-3": {"title": "Small Heading"},
|
||||
"code": {"title": "Code"},
|
||||
"quote": {"title": "Quote"},
|
||||
"unordered-list": {"title": "Generic List"},
|
||||
"ordered-list": {"title": "Numbered List"},
|
||||
"clean-block": {"title": "Clean block"},
|
||||
"link": {"title": "Create Link"},
|
||||
"image": {"title": "Insert Image"},
|
||||
"upload-image": {"title": "Import an image"},
|
||||
"table": {"title": "Insert Table"},
|
||||
"horizontal-rule": {"title": "Insert Horizontal Line"},
|
||||
"preview": {"title": "Toggle Preview"},
|
||||
"side-by-side": {"title": "Toggle Side by Side"},
|
||||
"fullscreen": {"title": "Toggle Fullscreen"},
|
||||
"guide": {"title": "Markdown Guide"},
|
||||
"undo": {"title": "Undo"},
|
||||
"redo": {"title": "Redo"}
|
||||
}
|
||||
},
|
||||
"ru": {
|
||||
"promptTexts": {
|
||||
"link": "Введите гиперссылку:",
|
||||
"image": "Вставьте ссылку на изображение:"
|
||||
},
|
||||
"status": {
|
||||
"lines": "строк",
|
||||
"words": "слов",
|
||||
"autosave": "Автосохранение: "
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user