mirror of
https://github.com/Ionaru/easy-markdown-editor
synced 2025-06-28 13:41:01 -06:00
Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2996b67ec9 | ||
|
1708e40c42 | ||
|
f1e229f5b8 | ||
|
a602d3b826 | ||
|
fe680f09f6 | ||
|
0eddf94930 | ||
|
22ce228b07 | ||
|
e7a56e11dd | ||
|
f20ff16b81 | ||
|
c93033bb4e | ||
|
c1b06a9613 | ||
|
bdfd0da5ff | ||
|
138c198852 | ||
|
a6b121f2e6 | ||
|
65dfecf484 | ||
|
97bf9ce8fd | ||
|
9b420ac103 | ||
|
f039bae67f | ||
|
c68bdf148a | ||
|
35587a9477 | ||
|
d9ab397b88 | ||
|
abead2a068 | ||
|
c25adab400 | ||
|
a49e867930 | ||
|
cb5564e1b2 | ||
|
fbc181f5c8 | ||
|
041594ae4a | ||
|
6ab32d9fd6 | ||
|
950f689dc7 | ||
|
6560950b65 | ||
|
f60c9b24c5 | ||
|
4b48564730 | ||
|
d26b4e399b | ||
|
84aafddd92 |
45
.github/workflows/cd.yaml
vendored
45
.github/workflows/cd.yaml
vendored
@ -12,42 +12,52 @@ on:
|
|||||||
- master
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
|
audit:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: current
|
||||||
|
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- run: npm audit --omit=dev
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
|
||||||
|
needs: [ audit ]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [ '12', '14', '16', '18' ]
|
node-version: [ '14', '16', '18' ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
- name: Checkout
|
- uses: actions/checkout@v4
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Audit
|
- run: npm ci
|
||||||
run: npm audit --production
|
|
||||||
|
|
||||||
- name: Install packages
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: npm test
|
run: npm test
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v4
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: cypress-screenshots
|
name: cypress-screenshots-nodejs-${{ matrix.node-version }}
|
||||||
path: cypress/screenshots
|
path: cypress/screenshots
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v4
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: cypress-videos
|
name: cypress-videos-nodejs-${{ matrix.node-version }}
|
||||||
path: cypress/videos
|
path: cypress/videos
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
@ -58,14 +68,13 @@ jobs:
|
|||||||
if: github.event_name == 'push'
|
if: github.event_name == 'push'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '16'
|
node-version: current
|
||||||
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install packages
|
- run: npm ci
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Deploy @latest version to npm
|
- name: Deploy @latest version to npm
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
39
CHANGELOG.md
39
CHANGELOG.md
@ -4,7 +4,25 @@ All notable changes to EasyMDE will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
[//]: # (## [Unreleased])
|
<!-- ## [Unreleased] -->
|
||||||
|
## [2.20.0] - 2025-03-04
|
||||||
|
### Added
|
||||||
|
- Support for `marked` extensions (Thanks to [@codingjoe], [#611], [#514]).
|
||||||
|
|
||||||
|
## [2.19.0] - 2025-02-18
|
||||||
|
### Added
|
||||||
|
- `updateStatusBar` type to typescript definitions (Thanks to [@borodean], [#519]).
|
||||||
|
- `"upload-image"` option to the `ToolbarButton` typescript definitions (Thanks to [@borodean], [#520]).
|
||||||
|
- `imageInputName` option to set a custom "name" attribute for the image input (Thanks to [@robinvandernoord], [#573]).
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Relative image paths using the stylesheet as the source instead of the document (Thanks to [@p1gp1g], [#591]).
|
||||||
|
- Excessive memory usage with the `previewImagesInEditor` option (Thanks to [@p1gp1g], [#592]).
|
||||||
|
- Parentheses in the alt text of images causing the image not to load then using `previewImagesInEditor` (Thanks to [@mayraamaral], [#608]).
|
||||||
|
|
||||||
|
## [2.18.0] - 2022-09-20
|
||||||
|
### Added
|
||||||
|
- `toolbarButtonClassPrefix` option to resolve conflicts with Bootstrap classes ([#493]).
|
||||||
|
|
||||||
## [2.17.0] - 2022-08-20
|
## [2.17.0] - 2022-08-20
|
||||||
### Added
|
### Added
|
||||||
@ -254,6 +272,9 @@ Project forked from [SimpleMDE](https://github.com/sparksuite/simplemde-markdown
|
|||||||
- Cursor not always showing in "text" mode over the edit field
|
- Cursor not always showing in "text" mode over the edit field
|
||||||
|
|
||||||
<!-- Linked issues -->
|
<!-- Linked issues -->
|
||||||
|
[#611]: https://github.com/Ionaru/easy-markdown-editor/issues/611
|
||||||
|
[#514]: https://github.com/Ionaru/easy-markdown-editor/issues/514
|
||||||
|
[#493]: https://github.com/Ionaru/easy-markdown-editor/issues/493
|
||||||
[#478]: https://github.com/Ionaru/easy-markdown-editor/issues/478
|
[#478]: https://github.com/Ionaru/easy-markdown-editor/issues/478
|
||||||
[#399]: https://github.com/Ionaru/easy-markdown-editor/issues/399
|
[#399]: https://github.com/Ionaru/easy-markdown-editor/issues/399
|
||||||
[#252]: https://github.com/Ionaru/easy-markdown-editor/issues/252
|
[#252]: https://github.com/Ionaru/easy-markdown-editor/issues/252
|
||||||
@ -274,6 +295,12 @@ Project forked from [SimpleMDE](https://github.com/sparksuite/simplemde-markdown
|
|||||||
[#9]: https://github.com/Ionaru/easy-markdown-editor/issues/9
|
[#9]: https://github.com/Ionaru/easy-markdown-editor/issues/9
|
||||||
|
|
||||||
<!-- Linked PRs -->
|
<!-- Linked PRs -->
|
||||||
|
[#608]: https://github.com/Ionaru/easy-markdown-editor/pull/608
|
||||||
|
[#592]: https://github.com/Ionaru/easy-markdown-editor/pull/592
|
||||||
|
[#591]: https://github.com/Ionaru/easy-markdown-editor/pull/591
|
||||||
|
[#573]: https://github.com/Ionaru/easy-markdown-editor/pull/573
|
||||||
|
[#520]: https://github.com/Ionaru/easy-markdown-editor/pull/520
|
||||||
|
[#519]: https://github.com/Ionaru/easy-markdown-editor/pull/519
|
||||||
[#492]: https://github.com/Ionaru/easy-markdown-editor/pull/492
|
[#492]: https://github.com/Ionaru/easy-markdown-editor/pull/492
|
||||||
[#488]: https://github.com/Ionaru/easy-markdown-editor/pull/488
|
[#488]: https://github.com/Ionaru/easy-markdown-editor/pull/488
|
||||||
[#486]: https://github.com/Ionaru/easy-markdown-editor/pull/486
|
[#486]: https://github.com/Ionaru/easy-markdown-editor/pull/486
|
||||||
@ -413,9 +440,17 @@ Project forked from [SimpleMDE](https://github.com/sparksuite/simplemde-markdown
|
|||||||
[@hlf20010508]: https://github.com/hlf20010508
|
[@hlf20010508]: https://github.com/hlf20010508
|
||||||
[@ZsgsDesign]: https://github.com/ZsgsDesign
|
[@ZsgsDesign]: https://github.com/ZsgsDesign
|
||||||
[@sghoweri]: https://github.com/sghoweri
|
[@sghoweri]: https://github.com/sghoweri
|
||||||
|
[@borodean]: https://github.com/borodean
|
||||||
|
[@robinvandernoord]: https://github.com/robinvandernoord
|
||||||
|
[@p1gp1g]: https://github.com/p1gp1g
|
||||||
|
[@mayraamaral]: https://github.com/mayraamaral
|
||||||
|
[@codingjoe]: https://github.com/codingjoe
|
||||||
|
|
||||||
<!-- Linked versions -->
|
<!-- Linked versions -->
|
||||||
[Unreleased]: https://github.com/Ionaru/easy-markdown-editor/compare/2.17.0...HEAD
|
[Unreleased]: https://github.com/Ionaru/easy-markdown-editor/compare/2.20.0...HEAD
|
||||||
|
[2.20.0]: https://github.com/Ionaru/easy-markdown-editor/compare/2.19.0...2.20.0
|
||||||
|
[2.19.0]: https://github.com/Ionaru/easy-markdown-editor/compare/2.18.0...2.19.0
|
||||||
|
[2.18.0]: https://github.com/Ionaru/easy-markdown-editor/compare/2.17.0...2.18.0
|
||||||
[2.17.0]: https://github.com/Ionaru/easy-markdown-editor/compare/2.16.1...2.17.0
|
[2.17.0]: https://github.com/Ionaru/easy-markdown-editor/compare/2.16.1...2.17.0
|
||||||
[2.16.1]: https://github.com/Ionaru/easy-markdown-editor/compare/2.16.0...2.16.1
|
[2.16.1]: https://github.com/Ionaru/easy-markdown-editor/compare/2.16.0...2.16.1
|
||||||
[2.16.0]: https://github.com/Ionaru/easy-markdown-editor/compare/2.15.0...2.16.0
|
[2.16.0]: https://github.com/Ionaru/easy-markdown-editor/compare/2.15.0...2.16.0
|
||||||
|
11
README.md
11
README.md
@ -1,8 +1,9 @@
|
|||||||
# EasyMDE - Markdown Editor
|
# EasyMDE - Markdown Editor
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/easymde)
|
[](https://www.npmjs.com/package/easymde)
|
||||||
[](https://www.npmjs.com/package/easymde/v/next)
|
[](https://www.npmjs.com/package/easymde/v/next)
|
||||||
[](https://github.com/Ionaru/easy-markdown-editor/actions)
|
[](https://www.npmjs.com/package/easymde/v/v3-alpha)
|
||||||
|
[](https://github.com/Ionaru/easy-markdown-editor/actions?query=branch%3Amaster)
|
||||||
|
|
||||||
> This repository is a fork of
|
> This repository is a fork of
|
||||||
[SimpleMDE, made by Sparksuite](https://github.com/sparksuite/simplemde-markdown-editor/).
|
[SimpleMDE, made by Sparksuite](https://github.com/sparksuite/simplemde-markdown-editor/).
|
||||||
@ -16,9 +17,9 @@ In addition, the syntax is rendered while editing to clearly show the expected r
|
|||||||
EasyMDE also features both built-in auto saving and spell checking.
|
EasyMDE also features both built-in auto saving and spell checking.
|
||||||
The editor is entirely customizable, from theming to toolbar buttons and javascript hooks.
|
The editor is entirely customizable, from theming to toolbar buttons and javascript hooks.
|
||||||
|
|
||||||
[**Try the demo**](https://easy-markdown-editor.tk/)
|
[**Try the demo**](https://stackblitz.com/edit/easymde/)
|
||||||
|
|
||||||
[](https://easy-markdown-editor.tk/)
|
[](https://stackblitz.com/edit/easymde/)
|
||||||
|
|
||||||
|
|
||||||
## Quick access
|
## Quick access
|
||||||
@ -206,6 +207,7 @@ easyMDE.value('New input for **EasyMDE**');
|
|||||||
- **theme**: Override the theme. Defaults to `easymde`.
|
- **theme**: Override the theme. Defaults to `easymde`.
|
||||||
- **toolbar**: If set to `false`, hide the toolbar. Defaults to the [array of icons](#toolbar-icons).
|
- **toolbar**: If set to `false`, hide the toolbar. Defaults to the [array of icons](#toolbar-icons).
|
||||||
- **toolbarTips**: If set to `false`, disable toolbar button tips. Defaults to `true`.
|
- **toolbarTips**: If set to `false`, disable toolbar button tips. Defaults to `true`.
|
||||||
|
- **toolbarButtonClassPrefix**: Adds a prefix to the toolbar button classes when set. For example, a value of `"mde"` results in `"mde-bold"` for the Bold button.
|
||||||
- **direction**: `rtl` or `ltr`. Changes text direction to support right-to-left languages. Defaults to `ltr`.
|
- **direction**: `rtl` or `ltr`. Changes text direction to support right-to-left languages. Defaults to `ltr`.
|
||||||
|
|
||||||
|
|
||||||
@ -311,6 +313,7 @@ const editor = new EasyMDE({
|
|||||||
tabSize: 4,
|
tabSize: 4,
|
||||||
toolbar: false,
|
toolbar: false,
|
||||||
toolbarTips: false,
|
toolbarTips: false,
|
||||||
|
toolbarButtonClassPrefix: "mde",
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -5,5 +5,6 @@ export default defineConfig({
|
|||||||
excludeSpecPattern: [
|
excludeSpecPattern: [
|
||||||
'**/*.html',
|
'**/*.html',
|
||||||
],
|
],
|
||||||
|
video: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,8 @@ describe('URL prompts', () => {
|
|||||||
|
|
||||||
cy.window().then(($win) => {
|
cy.window().then(($win) => {
|
||||||
const stub = cy.stub($win, 'prompt');
|
const stub = cy.stub($win, 'prompt');
|
||||||
cy.get('button.link').click().then(() => {
|
cy.get('button.link').click();
|
||||||
|
cy.get('button.link').then(() => {
|
||||||
expect(stub).to.be.calledWith('URL for the link:', 'https://');
|
expect(stub).to.be.calledWith('URL for the link:', 'https://');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -23,7 +24,8 @@ describe('URL prompts', () => {
|
|||||||
|
|
||||||
cy.window().then(($win) => {
|
cy.window().then(($win) => {
|
||||||
const stub = cy.stub($win, 'prompt');
|
const stub = cy.stub($win, 'prompt');
|
||||||
cy.get('button.image').click().then(() => {
|
cy.get('button.image').click();
|
||||||
|
cy.get('button.image').then(() => {
|
||||||
expect(stub).to.be.calledWith('URL of the image:', 'https://');
|
expect(stub).to.be.calledWith('URL of the image:', 'https://');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -52,7 +54,8 @@ describe('URL prompts', () => {
|
|||||||
cy.window().then(($win) => {
|
cy.window().then(($win) => {
|
||||||
const stub = cy.stub($win, 'prompt');
|
const stub = cy.stub($win, 'prompt');
|
||||||
stub.returns('https://example.com');
|
stub.returns('https://example.com');
|
||||||
cy.get('button.link').click().then(() => {
|
cy.get('button.link').click();
|
||||||
|
cy.get('button.link').then(() => {
|
||||||
expect(stub).to.be.calledWith('URL for the link:', 'https://');
|
expect(stub).to.be.calledWith('URL for the link:', 'https://');
|
||||||
stub.restore();
|
stub.restore();
|
||||||
});
|
});
|
||||||
@ -63,7 +66,8 @@ describe('URL prompts', () => {
|
|||||||
cy.window().then(($win) => {
|
cy.window().then(($win) => {
|
||||||
const stub = cy.stub($win, 'prompt');
|
const stub = cy.stub($win, 'prompt');
|
||||||
stub.returns('https://example.eu');
|
stub.returns('https://example.eu');
|
||||||
cy.get('button.link').click().then(() => {
|
cy.get('button.link').click();
|
||||||
|
cy.get('button.link').then(() => {
|
||||||
expect(stub).to.be.calledWith('URL for the link:', 'https://');
|
expect(stub).to.be.calledWith('URL for the link:', 'https://');
|
||||||
stub.restore();
|
stub.restore();
|
||||||
});
|
});
|
||||||
|
17
cypress/e2e/3-class-prefix/class-prefix.cy.js
Normal file
17
cypress/e2e/3-class-prefix/class-prefix.cy.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
describe('Default editor', () => {
|
||||||
|
it('table', () => {
|
||||||
|
cy.visit(__dirname + '/index-no-prefix.html');
|
||||||
|
|
||||||
|
cy.get('button.table').should('be.visible');
|
||||||
|
cy.get('button.table').invoke('outerWidth').should('not.equal', 30);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('loads the editor with default settings', () => {
|
||||||
|
cy.visit(__dirname + '/index.html');
|
||||||
|
|
||||||
|
cy.get('button.mde-table').should('be.visible');
|
||||||
|
cy.get('button.mde-table').invoke('outerWidth').should('equal', 30);
|
||||||
|
});
|
||||||
|
});
|
21
cypress/e2e/3-class-prefix/index-no-prefix.html
Normal file
21
cypress/e2e/3-class-prefix/index-no-prefix.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Default</title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="../../../dist/easymde.min.css">
|
||||||
|
<script src="../../../dist/easymde.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<textarea id="textarea"></textarea>
|
||||||
|
<script>
|
||||||
|
const easyMDE = new EasyMDE({
|
||||||
|
showIcons: ["table"],
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
22
cypress/e2e/3-class-prefix/index.html
Normal file
22
cypress/e2e/3-class-prefix/index.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Default</title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="../../../dist/easymde.min.css">
|
||||||
|
<script src="../../../dist/easymde.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<textarea id="textarea"></textarea>
|
||||||
|
<script>
|
||||||
|
const easyMDE = new EasyMDE({
|
||||||
|
toolbarButtonClassPrefix: 'mde',
|
||||||
|
showIcons: ["table"],
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
43
cypress/e2e/4.image-rendering/image-rendering.cy.js
Normal file
43
cypress/e2e/4.image-rendering/image-rendering.cy.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
describe('Image rendering', () => {
|
||||||
|
|
||||||
|
const imageUrl = 'https://picsum.photos/id/237/150';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit(__dirname + '/index.html');
|
||||||
|
cy.intercept('GET', imageUrl).as('image');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must render an image inside the editor', () => {
|
||||||
|
cy.get('.EasyMDEContainer').should('be.visible');
|
||||||
|
cy.get('#textarea').should('not.be.visible');
|
||||||
|
|
||||||
|
cy.get('.EasyMDEContainer .CodeMirror').type(imageUrl);
|
||||||
|
cy.get('.EasyMDEContainer .CodeMirror').type('{home}');
|
||||||
|
|
||||||
|
cy.wait('@image');
|
||||||
|
|
||||||
|
cy.get(`.EasyMDEContainer [data-img-src="${imageUrl}"]`).should('be.visible');
|
||||||
|
|
||||||
|
cy.previewOn();
|
||||||
|
|
||||||
|
cy.get('.EasyMDEContainer .editor-preview').should('contain.html', `<p><img src="${imageUrl}" alt="Dog!"></p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must be able to handle parentheses inside image alt text', () => {
|
||||||
|
cy.get('.EasyMDEContainer').should('be.visible');
|
||||||
|
cy.get('#textarea').should('not.be.visible');
|
||||||
|
|
||||||
|
cy.get('.EasyMDEContainer .CodeMirror').type(imageUrl);
|
||||||
|
cy.get('.EasyMDEContainer .CodeMirror').type('{home}');
|
||||||
|
|
||||||
|
cy.wait('@image');
|
||||||
|
|
||||||
|
cy.get(`.EasyMDEContainer [data-img-src="${imageUrl}"]`).should('be.visible');
|
||||||
|
|
||||||
|
cy.previewOn();
|
||||||
|
|
||||||
|
cy.get('.EasyMDEContainer .editor-preview').should('contain.html', `<p><img src="${imageUrl}" alt="Dog! (He's a good boy!)"></p>`);
|
||||||
|
});
|
||||||
|
});
|
20
cypress/e2e/4.image-rendering/index.html
Normal file
20
cypress/e2e/4.image-rendering/index.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Default</title>
|
||||||
|
<link rel="stylesheet" href="../../../dist/easymde.min.css">
|
||||||
|
<script src="../../../dist/easymde.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<textarea id="textarea"></textarea>
|
||||||
|
<script>
|
||||||
|
const easyMDE = new EasyMDE({
|
||||||
|
previewImagesInEditor: true,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
24
cypress/e2e/5-marked-options/index.html
Normal file
24
cypress/e2e/5-marked-options/index.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Default</title>
|
||||||
|
<link rel="stylesheet" href="../../../dist/easymde.min.css">
|
||||||
|
<script src="../../../dist/easymde.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<textarea id="textarea"></textarea>
|
||||||
|
<script>
|
||||||
|
const easyMDE = new EasyMDE({
|
||||||
|
renderingConfig: {
|
||||||
|
markedOptions: {
|
||||||
|
headerPrefix: 'header-prefix-',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
18
cypress/e2e/5-marked-options/marked-options.cy.js
Normal file
18
cypress/e2e/5-marked-options/marked-options.cy.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
describe('Marked options', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit(__dirname + '/index.html');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must apply the markedOptions to the markdown parser', () => {
|
||||||
|
cy.get('.EasyMDEContainer').should('be.visible');
|
||||||
|
cy.get('#textarea').should('not.be.visible');
|
||||||
|
|
||||||
|
cy.get('.EasyMDEContainer .CodeMirror').type('# Title{enter}');
|
||||||
|
|
||||||
|
cy.previewOn();
|
||||||
|
|
||||||
|
cy.get('.EasyMDEContainer .editor-preview').should('contain.html', '<h1 id="header-prefix-title">Title</h1>');
|
||||||
|
});
|
||||||
|
});
|
1211
package-lock.json
generated
1211
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "easymde",
|
"name": "easymde",
|
||||||
"version": "2.17.0",
|
"version": "2.20.0",
|
||||||
"description": "A simple, beautiful, and embeddable JavaScript Markdown editor that easy to use. Features include autosaving and spell checking.",
|
"description": "A simple, beautiful, and embeddable JavaScript Markdown editor that easy to use. Features include autosaving and spell checking.",
|
||||||
"files": [
|
"files": [
|
||||||
"dist/**/*",
|
"dist/**/*",
|
||||||
@ -19,27 +19,27 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Jeroen Akkerman",
|
"author": "Jeroen Akkerman",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/codemirror": "^5.60.4",
|
"@types/codemirror": "^5.60.10",
|
||||||
"@types/marked": "^4.0.1",
|
"@types/marked": "^4.0.7",
|
||||||
"codemirror": "^5.63.1",
|
"codemirror": "^5.65.15",
|
||||||
"codemirror-spell-checker": "1.1.2",
|
"codemirror-spell-checker": "1.1.2",
|
||||||
"marked": "^4.0.18"
|
"marked": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"browserify": "^17.0.0",
|
"browserify": "^17.0.0",
|
||||||
"cypress": "^10.3.1",
|
"cypress": "^13.2.0",
|
||||||
"eslint": "^8.20.0",
|
"eslint": "^8.50.0",
|
||||||
"eslint-plugin-cypress": "^2.12.1",
|
"eslint-plugin-cypress": "^2.15.1",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"gulp-clean-css": "^4.2.0",
|
"gulp-clean-css": "^4.3.0",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"gulp-eslint": "^6.0.0",
|
"gulp-eslint": "^6.0.0",
|
||||||
"gulp-header": "^2.0.9",
|
"gulp-header": "^2.0.9",
|
||||||
"gulp-rename": "^2.0.0",
|
"gulp-rename": "^2.0.0",
|
||||||
"gulp-terser": "^2.1.0",
|
"gulp-terser": "^2.1.0",
|
||||||
"gulp-uglify": "^3.0.2",
|
"gulp-uglify": "^3.0.2",
|
||||||
"typescript": "^4.7.4",
|
"typescript": "^5.2.2",
|
||||||
"vinyl-buffer": "^1.0.0",
|
"vinyl-buffer": "^1.0.1",
|
||||||
"vinyl-source-stream": "^2.0.0"
|
"vinyl-source-stream": "^2.0.0"
|
||||||
},
|
},
|
||||||
"repository": "github:Ionaru/easy-markdown-editor",
|
"repository": "github:Ionaru/easy-markdown-editor",
|
||||||
|
@ -194,7 +194,8 @@ function createToolbarButton(options, enableActions, enableTooltips, shortcuts,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
el.className = options.name;
|
var classNamePrefix = parent.options.toolbarButtonClassPrefix ? parent.options.toolbarButtonClassPrefix + '-' : '';
|
||||||
|
el.className = classNamePrefix + options.name;
|
||||||
el.setAttribute('type', markup);
|
el.setAttribute('type', markup);
|
||||||
enableTooltips = (enableTooltips == undefined) ? true : enableTooltips;
|
enableTooltips = (enableTooltips == undefined) ? true : enableTooltips;
|
||||||
|
|
||||||
@ -1869,6 +1870,7 @@ function EasyMDE(options) {
|
|||||||
options.imagePathAbsolute = options.imagePathAbsolute || false;
|
options.imagePathAbsolute = options.imagePathAbsolute || false;
|
||||||
options.imageCSRFName = options.imageCSRFName || 'csrfmiddlewaretoken';
|
options.imageCSRFName = options.imageCSRFName || 'csrfmiddlewaretoken';
|
||||||
options.imageCSRFHeader = options.imageCSRFHeader || false;
|
options.imageCSRFHeader = options.imageCSRFHeader || false;
|
||||||
|
options.imageInputName = options.imageInputName || 'image';
|
||||||
|
|
||||||
|
|
||||||
// Change unique_id to uniqueId for backwards compatibility
|
// Change unique_id to uniqueId for backwards compatibility
|
||||||
@ -2043,7 +2045,7 @@ EasyMDE.prototype.markdown = function (text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set options
|
// Set options
|
||||||
marked.setOptions(markedOptions);
|
marked.use(markedOptions);
|
||||||
|
|
||||||
// Convert the markdown to HTML
|
// Convert the markdown to HTML
|
||||||
var htmlText = marked.parse(text);
|
var htmlText = marked.parse(text);
|
||||||
@ -2231,8 +2233,9 @@ EasyMDE.prototype.render = function (el) {
|
|||||||
|
|
||||||
|
|
||||||
function assignImageBlockAttributes(parentEl, img) {
|
function assignImageBlockAttributes(parentEl, img) {
|
||||||
parentEl.setAttribute('data-img-src', img.url);
|
var url = (new URL(img.url, document.baseURI)).href;
|
||||||
parentEl.setAttribute('style', '--bg-image:url(' + img.url + ');--width:' + img.naturalWidth + 'px;--height:' + calcHeight(img.naturalWidth, img.naturalHeight));
|
parentEl.setAttribute('data-img-src', url);
|
||||||
|
parentEl.setAttribute('style', '--bg-image:url(' + url + ');--width:' + img.naturalWidth + 'px;--height:' + calcHeight(img.naturalWidth, img.naturalHeight));
|
||||||
_vm.codemirror.setSize();
|
_vm.codemirror.setSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2248,7 +2251,7 @@ EasyMDE.prototype.render = function (el) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!parentEl.hasAttribute('data-img-src')) {
|
if (!parentEl.hasAttribute('data-img-src')) {
|
||||||
var srcAttr = parentEl.innerText.match('\\((.*)\\)'); // might require better parsing according to markdown spec
|
var srcAttr = parentEl.innerText.match(/!\[.*?\]\((.*?)\)/); // might require better parsing according to markdown spec
|
||||||
if (!window.EMDEimagesCache) {
|
if (!window.EMDEimagesCache) {
|
||||||
window.EMDEimagesCache = {};
|
window.EMDEimagesCache = {};
|
||||||
}
|
}
|
||||||
@ -2265,6 +2268,7 @@ EasyMDE.prototype.render = function (el) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!window.EMDEimagesCache[keySrc]) {
|
if (!window.EMDEimagesCache[keySrc]) {
|
||||||
|
window.EMDEimagesCache[keySrc] = {};
|
||||||
var img = document.createElement('img');
|
var img = document.createElement('img');
|
||||||
img.onload = function () {
|
img.onload = function () {
|
||||||
window.EMDEimagesCache[keySrc] = {
|
window.EMDEimagesCache[keySrc] = {
|
||||||
@ -2688,7 +2692,7 @@ EasyMDE.prototype.createToolbar = function (items) {
|
|||||||
imageInput.className = 'imageInput';
|
imageInput.className = 'imageInput';
|
||||||
imageInput.type = 'file';
|
imageInput.type = 'file';
|
||||||
imageInput.multiple = true;
|
imageInput.multiple = true;
|
||||||
imageInput.name = 'image';
|
imageInput.name = self.options.imageInputName;
|
||||||
imageInput.accept = self.options.imageAccept;
|
imageInput.accept = self.options.imageAccept;
|
||||||
imageInput.style.display = 'none';
|
imageInput.style.display = 'none';
|
||||||
imageInput.style.opacity = 0;
|
imageInput.style.opacity = 0;
|
||||||
|
@ -103,6 +103,7 @@ const editor2 = new EasyMDE({
|
|||||||
});
|
});
|
||||||
|
|
||||||
editor2.clearAutosavedValue();
|
editor2.clearAutosavedValue();
|
||||||
|
editor2.updateStatusBar('upload-image', 'Drag & drop images!');
|
||||||
|
|
||||||
EasyMDE.togglePreview(editor2);
|
EasyMDE.togglePreview(editor2);
|
||||||
EasyMDE.toggleSideBySide(editor2);
|
EasyMDE.toggleSideBySide(editor2);
|
||||||
@ -177,6 +178,7 @@ const editorImagesCustom = new EasyMDE({
|
|||||||
});
|
});
|
||||||
|
|
||||||
new EasyMDE({
|
new EasyMDE({
|
||||||
|
toolbarButtonClassPrefix: 'mde',
|
||||||
sideBySideFullscreen: true,
|
sideBySideFullscreen: true,
|
||||||
lineNumbers: false,
|
lineNumbers: false,
|
||||||
unorderedListStyle: '*',
|
unorderedListStyle: '*',
|
||||||
@ -208,6 +210,7 @@ new EasyMDE({
|
|||||||
'unordered-list',
|
'unordered-list',
|
||||||
'ordered-list',
|
'ordered-list',
|
||||||
'table',
|
'table',
|
||||||
|
'upload-image',
|
||||||
'|',
|
'|',
|
||||||
'link',
|
'link',
|
||||||
],
|
],
|
||||||
@ -215,8 +218,21 @@ new EasyMDE({
|
|||||||
|
|
||||||
new EasyMDE({
|
new EasyMDE({
|
||||||
direction: 'ltr',
|
direction: 'ltr',
|
||||||
})
|
});
|
||||||
|
|
||||||
new EasyMDE({
|
new EasyMDE({
|
||||||
direction: 'rtl',
|
direction: 'rtl',
|
||||||
})
|
});
|
||||||
|
|
||||||
|
new EasyMDE({
|
||||||
|
previewRender: (plainText: string) => {
|
||||||
|
return '<pre>' + plainText + '</pre>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
new EasyMDE({
|
||||||
|
previewRender: (plainText: string, preview) => {
|
||||||
|
preview.innerHTML = '<pre>' + plainText + '</pre>';
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
7
types/easymde.d.ts
vendored
7
types/easymde.d.ts
vendored
@ -35,6 +35,7 @@ type ToolbarButton =
|
|||||||
| 'ordered-list'
|
| 'ordered-list'
|
||||||
| 'link'
|
| 'link'
|
||||||
| 'image'
|
| 'image'
|
||||||
|
| 'upload-image'
|
||||||
| 'strikethrough'
|
| 'strikethrough'
|
||||||
| 'code'
|
| 'code'
|
||||||
| 'table'
|
| 'table'
|
||||||
@ -100,7 +101,7 @@ declare namespace EasyMDE {
|
|||||||
interface RenderingOptions {
|
interface RenderingOptions {
|
||||||
codeSyntaxHighlighting?: boolean;
|
codeSyntaxHighlighting?: boolean;
|
||||||
hljs?: any;
|
hljs?: any;
|
||||||
markedOptions?: marked.MarkedOptions;
|
markedOptions?: marked.MarkedExtension;
|
||||||
sanitizerFunction?: (html: string) => string;
|
sanitizerFunction?: (html: string) => string;
|
||||||
singleLineBreaks?: boolean;
|
singleLineBreaks?: boolean;
|
||||||
}
|
}
|
||||||
@ -210,6 +211,7 @@ declare namespace EasyMDE {
|
|||||||
tabSize?: number;
|
tabSize?: number;
|
||||||
toolbar?: boolean | ReadonlyArray<'|' | ToolbarButton | ToolbarIcon | ToolbarDropdownIcon>;
|
toolbar?: boolean | ReadonlyArray<'|' | ToolbarButton | ToolbarIcon | ToolbarDropdownIcon>;
|
||||||
toolbarTips?: boolean;
|
toolbarTips?: boolean;
|
||||||
|
toolbarButtonClassPrefix?: string;
|
||||||
onToggleFullScreen?: (goingIntoFullScreen: boolean) => void;
|
onToggleFullScreen?: (goingIntoFullScreen: boolean) => void;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
scrollbarStyle?: string;
|
scrollbarStyle?: string;
|
||||||
@ -225,6 +227,7 @@ declare namespace EasyMDE {
|
|||||||
imageCSRFName?: string;
|
imageCSRFName?: string;
|
||||||
imageCSRFHeader?: boolean;
|
imageCSRFHeader?: boolean;
|
||||||
imageTexts?: ImageTextsOptions;
|
imageTexts?: ImageTextsOptions;
|
||||||
|
imageInputName?: string
|
||||||
errorMessages?: ImageErrorTextsOptions;
|
errorMessages?: ImageErrorTextsOptions;
|
||||||
errorCallback?: (errorMessage: string) => void;
|
errorCallback?: (errorMessage: string) => void;
|
||||||
|
|
||||||
@ -257,6 +260,8 @@ declare class EasyMDE {
|
|||||||
|
|
||||||
clearAutosavedValue(): void;
|
clearAutosavedValue(): void;
|
||||||
|
|
||||||
|
updateStatusBar(itemName: string, content: string): void;
|
||||||
|
|
||||||
static toggleBold: (editor: EasyMDE) => void;
|
static toggleBold: (editor: EasyMDE) => void;
|
||||||
static toggleItalic: (editor: EasyMDE) => void;
|
static toggleItalic: (editor: EasyMDE) => void;
|
||||||
static toggleStrikethrough: (editor: EasyMDE) => void;
|
static toggleStrikethrough: (editor: EasyMDE) => void;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es3",
|
"target": "es3",
|
||||||
|
"ignoreDeprecations": "5.0",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noEmit": true
|
"noEmit": true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user