2
0
mirror of https://github.com/Ionaru/easy-markdown-editor synced 2025-10-08 21:42:12 -06:00

Compare commits

..

No commits in common. "master" and "2.18.0" have entirely different histories.

15 changed files with 678 additions and 582 deletions

View File

@ -18,11 +18,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/setup-node@v4 - uses: actions/setup-node@v3
with: with:
node-version: current node-version: current
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- run: npm audit --omit=dev - run: npm audit --omit=dev
@ -36,28 +36,28 @@ jobs:
node-version: [ '14', '16', '18' ] node-version: [ '14', '16', '18' ]
steps: steps:
- uses: actions/setup-node@v4 - uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- run: npm ci - run: npm ci
- name: Test - name: Test
run: npm test run: npm test
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: cypress-screenshots-nodejs-${{ matrix.node-version }} name: cypress-screenshots
path: cypress/screenshots path: cypress/screenshots
retention-days: 7 retention-days: 7
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
if: always() if: always()
with: with:
name: cypress-videos-nodejs-${{ matrix.node-version }} name: cypress-videos
path: cypress/videos path: cypress/videos
retention-days: 7 retention-days: 7
@ -68,11 +68,11 @@ jobs:
if: github.event_name == 'push' if: github.event_name == 'push'
steps: steps:
- uses: actions/setup-node@v4 - uses: actions/setup-node@v3
with: with:
node-version: current node-version: current
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- run: npm ci - run: npm ci

View File

@ -5,21 +5,6 @@ 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 ## [2.18.0] - 2022-09-20
### Added ### Added
- `toolbarButtonClassPrefix` option to resolve conflicts with Bootstrap classes ([#493]). - `toolbarButtonClassPrefix` option to resolve conflicts with Bootstrap classes ([#493]).
@ -272,8 +257,6 @@ 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 [#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
@ -295,12 +278,6 @@ 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
@ -440,16 +417,9 @@ 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.20.0...HEAD [Unreleased]: https://github.com/Ionaru/easy-markdown-editor/compare/2.18.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.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

View File

@ -1,9 +1,8 @@
# EasyMDE - Markdown Editor # EasyMDE - Markdown Editor
[![npm version](https://img.shields.io/npm/v/easymde.svg?style=for-the-badge)](https://www.npmjs.com/package/easymde) [![npm version](https://img.shields.io/npm/v/easymde.svg?style=for-the-badge)](https://www.npmjs.com/package/easymde)
[![npm @next version](https://img.shields.io/npm/v/easymde/next.svg?style=for-the-badge)](https://www.npmjs.com/package/easymde/v/next) [![npm version](https://img.shields.io/npm/v/easymde/next.svg?style=for-the-badge)](https://www.npmjs.com/package/easymde/v/next)
[![npm @v3-alpha version](https://img.shields.io/npm/v/easymde/v3-alpha.svg?style=for-the-badge)](https://www.npmjs.com/package/easymde/v/v3-alpha) [![Build Status](https://img.shields.io/github/workflow/status/ionaru/easy-markdown-editor/Test%20&%20Deploy/master?style=for-the-badge)](https://github.com/Ionaru/easy-markdown-editor/actions)
[![Build Status](https://img.shields.io/github/actions/workflow/status/ionaru/easy-markdown-editor/cd.yaml?branch=master&style=for-the-badge)](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/).
@ -17,9 +16,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://stackblitz.com/edit/easymde/) [**Try the demo**](https://easy-markdown-editor.tk/)
[![Preview](https://user-images.githubusercontent.com/3472373/51319377-26fe6e00-1a5d-11e9-8cc6-3137a566796d.png)](https://stackblitz.com/edit/easymde/) [![Preview](https://user-images.githubusercontent.com/3472373/51319377-26fe6e00-1a5d-11e9-8cc6-3137a566796d.png)](https://easy-markdown-editor.tk/)
## Quick access ## Quick access

View File

@ -5,6 +5,5 @@ export default defineConfig({
excludeSpecPattern: [ excludeSpecPattern: [
'**/*.html', '**/*.html',
], ],
video: true,
}, },
}); });

View File

@ -11,8 +11,7 @@ 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(); cy.get('button.link').click().then(() => {
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://');
}); });
}); });
@ -24,8 +23,7 @@ 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(); cy.get('button.image').click().then(() => {
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://');
}); });
}); });
@ -54,8 +52,7 @@ 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(); cy.get('button.link').click().then(() => {
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();
}); });
@ -66,8 +63,7 @@ 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(); cy.get('button.link').click().then(() => {
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();
}); });

View File

@ -1,43 +0,0 @@
/// <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}![Dog!]({end})');
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}![Dog! (He\'s a good boy!)]({end})');
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>`);
});
});

View File

@ -1,20 +0,0 @@
<!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>

View File

@ -1,24 +0,0 @@
<!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>

View File

@ -1,18 +0,0 @@
/// <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>');
});
});

1041
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "easymde", "name": "easymde",
"version": "2.20.0", "version": "2.18.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.10", "@types/codemirror": "^5.60.4",
"@types/marked": "^4.0.7", "@types/marked": "^4.0.7",
"codemirror": "^5.65.15", "codemirror": "^5.63.1",
"codemirror-spell-checker": "1.1.2", "codemirror-spell-checker": "1.1.2",
"marked": "^4.1.0" "marked": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
"browserify": "^17.0.0", "browserify": "^17.0.0",
"cypress": "^13.2.0", "cypress": "^10.8.0",
"eslint": "^8.50.0", "eslint": "^8.23.1",
"eslint-plugin-cypress": "^2.15.1", "eslint-plugin-cypress": "^2.12.1",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-clean-css": "^4.3.0", "gulp-clean-css": "^4.2.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": "^5.2.2", "typescript": "^4.8.3",
"vinyl-buffer": "^1.0.1", "vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^2.0.0" "vinyl-source-stream": "^2.0.0"
}, },
"repository": "github:Ionaru/easy-markdown-editor", "repository": "github:Ionaru/easy-markdown-editor",

View File

@ -1870,7 +1870,6 @@ 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
@ -2045,7 +2044,7 @@ EasyMDE.prototype.markdown = function (text) {
} }
// Set options // Set options
marked.use(markedOptions); marked.setOptions(markedOptions);
// Convert the markdown to HTML // Convert the markdown to HTML
var htmlText = marked.parse(text); var htmlText = marked.parse(text);
@ -2233,9 +2232,8 @@ EasyMDE.prototype.render = function (el) {
function assignImageBlockAttributes(parentEl, img) { function assignImageBlockAttributes(parentEl, img) {
var url = (new URL(img.url, document.baseURI)).href; parentEl.setAttribute('data-img-src', img.url);
parentEl.setAttribute('data-img-src', url); parentEl.setAttribute('style', '--bg-image:url(' + img.url + ');--width:' + img.naturalWidth + 'px;--height:' + calcHeight(img.naturalWidth, img.naturalHeight));
parentEl.setAttribute('style', '--bg-image:url(' + url + ');--width:' + img.naturalWidth + 'px;--height:' + calcHeight(img.naturalWidth, img.naturalHeight));
_vm.codemirror.setSize(); _vm.codemirror.setSize();
} }
@ -2251,7 +2249,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 = {};
} }
@ -2268,7 +2266,6 @@ 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] = {
@ -2692,7 +2689,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 = self.options.imageInputName; imageInput.name = 'image';
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;

View File

@ -103,7 +103,6 @@ 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);
@ -210,7 +209,6 @@ new EasyMDE({
'unordered-list', 'unordered-list',
'ordered-list', 'ordered-list',
'table', 'table',
'upload-image',
'|', '|',
'link', 'link',
], ],

6
types/easymde.d.ts vendored
View File

@ -35,7 +35,6 @@ type ToolbarButton =
| 'ordered-list' | 'ordered-list'
| 'link' | 'link'
| 'image' | 'image'
| 'upload-image'
| 'strikethrough' | 'strikethrough'
| 'code' | 'code'
| 'table' | 'table'
@ -101,7 +100,7 @@ declare namespace EasyMDE {
interface RenderingOptions { interface RenderingOptions {
codeSyntaxHighlighting?: boolean; codeSyntaxHighlighting?: boolean;
hljs?: any; hljs?: any;
markedOptions?: marked.MarkedExtension; markedOptions?: marked.MarkedOptions;
sanitizerFunction?: (html: string) => string; sanitizerFunction?: (html: string) => string;
singleLineBreaks?: boolean; singleLineBreaks?: boolean;
} }
@ -227,7 +226,6 @@ 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;
@ -260,8 +258,6 @@ 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;

View File

@ -1,7 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es3", "target": "es3",
"ignoreDeprecations": "5.0",
"strict": true, "strict": true,
"noImplicitReturns": true, "noImplicitReturns": true,
"noEmit": true "noEmit": true