From 5d0294f5f5196070479e64bacdbf2d7ea9abf852 Mon Sep 17 00:00:00 2001
From: Zignature
Date: Sat, 15 Jan 2022 13:20:28 +0100
Subject: [PATCH 1/8] Fix issue #373 problems in urls with special characters
Added function to escape URLs entered via JS prompt.
It's a partial fix because people cannot be stopped entering URLs manually and forgetting to escape them.
---
src/js/easymde.js | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/js/easymde.js b/src/js/easymde.js
index cece3b0..72f7254 100644
--- a/src/js/easymde.js
+++ b/src/js/easymde.js
@@ -848,6 +848,8 @@ function drawLink(editor) {
if (!url) {
return false;
}
+
+ if (/[()<>]/.test(url)) url = escapeUrl(url);
}
_replaceSelection(cm, stat.link, options.insertTexts.link, url);
}
@@ -865,10 +867,26 @@ function drawImage(editor) {
if (!url) {
return false;
}
+
+ if (/[()<>]/.test(url)) url = escapeUrl(url);
}
_replaceSelection(cm, stat.image, options.insertTexts.image, url);
}
+/**
+ * Escape URLs to prevent breaking up rendered Markdown links
+ * @param url {string} The url of the link or image
+ */
+function escapeUrl(url) {
+
+ url = url.replace(/\(/g,'\\(')
+ .replace(/\)/g,'\\)')
+ .replace(//g,'\\>');
+
+ return url;
+}
+
/**
* Action for opening the browse-file window to upload an image to a server.
* @param editor {EasyMDE} The EasyMDE object
From 33489ab616bc2282d29287c1eb55f16948197f48 Mon Sep 17 00:00:00 2001
From: Zignature
Date: Sat, 15 Jan 2022 23:26:10 +0100
Subject: [PATCH 2/8] URL encoding and escaping for JS prompt URLs
- URL encoding and escaping added for JS prompt entered URLs
- added option escapeURLs (boolean)
---
src/js/easymde.js | 18 ++++++++++--------
types/easymde.d.ts | 1 +
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/src/js/easymde.js b/src/js/easymde.js
index 72f7254..b419d5d 100644
--- a/src/js/easymde.js
+++ b/src/js/easymde.js
@@ -849,7 +849,10 @@ function drawLink(editor) {
return false;
}
- if (/[()<>]/.test(url)) url = escapeUrl(url);
+ if (options.escapeURLs) {
+ url = encodeURI(url);
+ if (/[()]/.test(url)) url = escapeURI(url);
+ }
}
_replaceSelection(cm, stat.link, options.insertTexts.link, url);
}
@@ -868,7 +871,10 @@ function drawImage(editor) {
return false;
}
- if (/[()<>]/.test(url)) url = escapeUrl(url);
+ if (options.escapeURLs) {
+ url = encodeURI(url);
+ if (/[()]/.test(url)) url = escapeURI(url);
+ }
}
_replaceSelection(cm, stat.image, options.insertTexts.image, url);
}
@@ -877,12 +883,8 @@ function drawImage(editor) {
* Escape URLs to prevent breaking up rendered Markdown links
* @param url {string} The url of the link or image
*/
-function escapeUrl(url) {
-
- url = url.replace(/\(/g,'\\(')
- .replace(/\)/g,'\\)')
- .replace(//g,'\\>');
+function escapeURI(url) {
+ url = url.replace(/\(/g,'\\(').replace(/\)/g,'\\)');
return url;
}
diff --git a/types/easymde.d.ts b/types/easymde.d.ts
index 2aa161b..b082324 100644
--- a/types/easymde.d.ts
+++ b/types/easymde.d.ts
@@ -197,6 +197,7 @@ declare namespace EasyMDE {
previewImagesInEditor?: boolean;
previewRender?: (markdownPlaintext: string, previewElement: HTMLElement) => string;
promptURLs?: boolean;
+ escapeURLs?: boolean;
renderingConfig?: RenderingOptions;
shortcuts?: Shortcuts;
showIcons?: ReadonlyArray;
From c174b6f149ce9dd6d540beda91331ba7a936e593 Mon Sep 17 00:00:00 2001
From: Zignature
Date: Sat, 15 Jan 2022 23:34:05 +0100
Subject: [PATCH 3/8] Changed function name escapeURI to escapedPromptURL and
option escapeURLs to option escapePromptURLs
---
src/js/easymde.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/js/easymde.js b/src/js/easymde.js
index b419d5d..8aedf80 100644
--- a/src/js/easymde.js
+++ b/src/js/easymde.js
@@ -849,9 +849,9 @@ function drawLink(editor) {
return false;
}
- if (options.escapeURLs) {
+ if (options.escapePromptURLs) {
url = encodeURI(url);
- if (/[()]/.test(url)) url = escapeURI(url);
+ if (/[()]/.test(url)) url = escapePromptURL(url);
}
}
_replaceSelection(cm, stat.link, options.insertTexts.link, url);
@@ -871,9 +871,9 @@ function drawImage(editor) {
return false;
}
- if (options.escapeURLs) {
+ if (options.escapePromptURLs) {
url = encodeURI(url);
- if (/[()]/.test(url)) url = escapeURI(url);
+ if (/[()]/.test(url)) url = escapePromptURL(url);
}
}
_replaceSelection(cm, stat.image, options.insertTexts.image, url);
@@ -883,7 +883,7 @@ function drawImage(editor) {
* Escape URLs to prevent breaking up rendered Markdown links
* @param url {string} The url of the link or image
*/
-function escapeURI(url) {
+function escapePromptURL(url) {
url = url.replace(/\(/g,'\\(').replace(/\)/g,'\\)');
return url;
From 47f1e4f892b36b8171f043a9dc5d73a0efe9fef2 Mon Sep 17 00:00:00 2001
From: Zignature
Date: Sat, 15 Jan 2022 23:56:27 +0100
Subject: [PATCH 4/8] Updated readme and easymde.d.ts to reflect
escapePrompURLs option
---
README.md | 2 ++
types/easymde.d.ts | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f47da4c..fa0b07a 100644
--- a/README.md
+++ b/README.md
@@ -165,6 +165,7 @@ 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`.
+- **escapePromptURLs**: If set to `true`, urlencodes and escapes links entered via the JS prompt to prevent malformed Markdown rendered links. Only works when `promptURLs` is set to `true`. 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:`.
@@ -276,6 +277,7 @@ const editor = new EasyMDE({
return "Loading...";
},
promptURLs: true,
+ escapePromptURLs: true,
promptTexts: {
image: "Custom prompt for URL:",
link: "Custom prompt for URL:",
diff --git a/types/easymde.d.ts b/types/easymde.d.ts
index b082324..12ba258 100644
--- a/types/easymde.d.ts
+++ b/types/easymde.d.ts
@@ -197,7 +197,7 @@ declare namespace EasyMDE {
previewImagesInEditor?: boolean;
previewRender?: (markdownPlaintext: string, previewElement: HTMLElement) => string;
promptURLs?: boolean;
- escapeURLs?: boolean;
+ escapePromptURLs?: boolean;
renderingConfig?: RenderingOptions;
shortcuts?: Shortcuts;
showIcons?: ReadonlyArray;
From 16545eb0e1b0224e4e1402523aa85e1d0038d5a8 Mon Sep 17 00:00:00 2001
From: Zignature
Date: Sun, 16 Jan 2022 00:14:00 +0100
Subject: [PATCH 5/8] Made escaping prompt URLs automatic instead of optional
again
---
README.md | 2 --
src/js/easymde.js | 12 ++++--------
types/easymde.d.ts | 1 -
3 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index fa0b07a..f47da4c 100644
--- a/README.md
+++ b/README.md
@@ -165,7 +165,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`.
-- **escapePromptURLs**: If set to `true`, urlencodes and escapes links entered via the JS prompt to prevent malformed Markdown rendered links. Only works when `promptURLs` is set to `true`. 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:`.
@@ -277,7 +276,6 @@ const editor = new EasyMDE({
return "Loading...";
},
promptURLs: true,
- escapePromptURLs: true,
promptTexts: {
image: "Custom prompt for URL:",
link: "Custom prompt for URL:",
diff --git a/src/js/easymde.js b/src/js/easymde.js
index 8aedf80..db068ef 100644
--- a/src/js/easymde.js
+++ b/src/js/easymde.js
@@ -849,10 +849,8 @@ function drawLink(editor) {
return false;
}
- if (options.escapePromptURLs) {
- url = encodeURI(url);
- if (/[()]/.test(url)) url = escapePromptURL(url);
- }
+ url = encodeURI(url);
+ if (/[()]/.test(url)) url = escapePromptURL(url);
}
_replaceSelection(cm, stat.link, options.insertTexts.link, url);
}
@@ -871,10 +869,8 @@ function drawImage(editor) {
return false;
}
- if (options.escapePromptURLs) {
- url = encodeURI(url);
- if (/[()]/.test(url)) url = escapePromptURL(url);
- }
+ url = encodeURI(url);
+ if (/[()]/.test(url)) url = escapePromptURL(url);
}
_replaceSelection(cm, stat.image, options.insertTexts.image, url);
}
diff --git a/types/easymde.d.ts b/types/easymde.d.ts
index 12ba258..2aa161b 100644
--- a/types/easymde.d.ts
+++ b/types/easymde.d.ts
@@ -197,7 +197,6 @@ declare namespace EasyMDE {
previewImagesInEditor?: boolean;
previewRender?: (markdownPlaintext: string, previewElement: HTMLElement) => string;
promptURLs?: boolean;
- escapePromptURLs?: boolean;
renderingConfig?: RenderingOptions;
shortcuts?: Shortcuts;
showIcons?: ReadonlyArray;
From 0c2cf4cd51a0f1fe721e7dc70adfdc768449a20c Mon Sep 17 00:00:00 2001
From: Jeroen Akkerman
Date: Mon, 17 Jan 2022 00:04:18 +0100
Subject: [PATCH 6/8] Add tests for url prompts
---
.../{default.html => index.html} | 0
.../1-default-editor/preview.spec.js | 6 +-
.../1-default-editor/statusbar.spec.js | 2 +-
.../1-default-editor/visual.spec.js | 4 +-
cypress/integration/2-url-prompt/index.html | 20 ++
.../2-url-prompt/url-prompt.spec.js | 228 ++++++++++++++++++
cypress/support/commands.js | 16 ++
7 files changed, 269 insertions(+), 7 deletions(-)
rename cypress/integration/1-default-editor/{default.html => index.html} (100%)
create mode 100644 cypress/integration/2-url-prompt/index.html
create mode 100644 cypress/integration/2-url-prompt/url-prompt.spec.js
diff --git a/cypress/integration/1-default-editor/default.html b/cypress/integration/1-default-editor/index.html
similarity index 100%
rename from cypress/integration/1-default-editor/default.html
rename to cypress/integration/1-default-editor/index.html
diff --git a/cypress/integration/1-default-editor/preview.spec.js b/cypress/integration/1-default-editor/preview.spec.js
index ced582c..e437bbe 100644
--- a/cypress/integration/1-default-editor/preview.spec.js
+++ b/cypress/integration/1-default-editor/preview.spec.js
@@ -2,7 +2,7 @@
describe('Preview', () => {
beforeEach(() => {
- cy.visit(__dirname + '/default.html');
+ cy.visit(__dirname + '/index.html');
});
it('can show a preview of markdown text', () => {
@@ -22,9 +22,7 @@ describe('Preview', () => {
cy.get('.EasyMDEContainer .cm-strong').should('contain', '**');
cy.get('.EasyMDEContainer .cm-strong').should('contain', 'important');
- // Toggle preview.
- cy.get('.EasyMDEContainer .editor-toolbar button.preview').click();
- cy.get('.EasyMDEContainer .editor-preview').should('be.visible');
+ cy.previewOn();
// Check preview window for rendered markdown.
cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'My Big Title ');
diff --git a/cypress/integration/1-default-editor/statusbar.spec.js b/cypress/integration/1-default-editor/statusbar.spec.js
index 12e8276..9b96735 100644
--- a/cypress/integration/1-default-editor/statusbar.spec.js
+++ b/cypress/integration/1-default-editor/statusbar.spec.js
@@ -2,7 +2,7 @@
describe('Default statusbar', () => {
beforeEach(() => {
- cy.visit(__dirname + '/default.html');
+ cy.visit(__dirname + '/index.html');
});
it('loads the editor with default statusbar', () => {
diff --git a/cypress/integration/1-default-editor/visual.spec.js b/cypress/integration/1-default-editor/visual.spec.js
index 0ba1afc..18b7be2 100644
--- a/cypress/integration/1-default-editor/visual.spec.js
+++ b/cypress/integration/1-default-editor/visual.spec.js
@@ -2,10 +2,10 @@
describe('Default editor', () => {
beforeEach(() => {
- cy.visit(__dirname + '/default.html');
+ cy.visit(__dirname + '/index.html');
});
- it('Loads the editor with default settings', () => {
+ it('loads the editor with default settings', () => {
cy.get('.EasyMDEContainer').should('be.visible');
cy.get('#textarea').should('not.be.visible');
diff --git a/cypress/integration/2-url-prompt/index.html b/cypress/integration/2-url-prompt/index.html
new file mode 100644
index 0000000..aa5f9e5
--- /dev/null
+++ b/cypress/integration/2-url-prompt/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Default
+
+
+
+
+
+
+
+
+
+
diff --git a/cypress/integration/2-url-prompt/url-prompt.spec.js b/cypress/integration/2-url-prompt/url-prompt.spec.js
new file mode 100644
index 0000000..1436b12
--- /dev/null
+++ b/cypress/integration/2-url-prompt/url-prompt.spec.js
@@ -0,0 +1,228 @@
+///
+
+describe('URL prompts', () => {
+ beforeEach(() => {
+ cy.visit(__dirname + '/index.html');
+ });
+
+ it('must show the correct text for a link prompt', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ const stub = cy.stub($win, 'prompt');
+ cy.get('button.link').click().then(() => {
+ expect(stub).to.be.calledWith('URL for the link:', 'https://');
+ });
+ });
+ });
+
+ it('must show the correct text for an image prompt', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ const stub = cy.stub($win, 'prompt');
+ cy.get('button.image').click().then(() => {
+ expect(stub).to.be.calledWith('URL of the image:', 'https://');
+ });
+ });
+ });
+
+ it('must enter a link correctly through a prompt', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com)');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a website!
');
+ });
+
+ it('can use the prompt multiple times', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ const stub = cy.stub($win, 'prompt');
+ stub.returns('https://example.com');
+ cy.get('button.link').click().then(() => {
+ expect(stub).to.be.calledWith('URL for the link:', 'https://');
+ stub.restore();
+ });
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com)');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!{end}{enter}');
+
+ cy.window().then(($win) => {
+ const stub = cy.stub($win, 'prompt');
+ stub.returns('https://example.eu');
+ cy.get('button.link').click().then(() => {
+ expect(stub).to.be.calledWith('URL for the link:', 'https://');
+ stub.restore();
+ });
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.eu)');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a second website!');
+
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[Link to a website!](https://example.com)');
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[Link to a second website!](https://example.eu)');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should(
+ 'contain.html',
+ 'Link to a website! Link to a second website!
',
+ );
+ });
+
+ it('must be able to deal with parameters in links', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=param&moo=cow');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com?some=param&moo=cow)');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a website!
');
+ });
+
+ it('must be able to deal with brackets in links', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=[]param');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com?some=%5B%5Dparam)');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a website!
');
+ });
+
+ it('must be able to deal with parentheses in links', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=(param)');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com?some=\\(param\\))');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a website!
');
+ });
+
+ it('must be able to deal with parentheses in links (multiple)', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=(param1,param2)&more=(param3,param4)&end=true');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com?some=\\(param1,param2\\)&more=\\(param3,param4\\)&end=true)');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a website!
');
+ });
+
+ it('must be able to deal with unbalanced parentheses in links (opening)', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=(param');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com?some=\\(param)');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a website!
');
+ });
+
+ it('must be able to deal with unbalanced parentheses in links (closing)', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=)param');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com?some=\\)param)');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a website!
');
+ });
+
+ it('must be able to deal with inequality symbols in links', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=Link to a website!
');
+ });
+
+ it('must be able to deal with emoji in links', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=👷♂️');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com?some=%F0%9F%91%B7%E2%80%8D%E2%99%82%EF%B8%8F');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a 👌 website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a 👌 website!
');
+ });
+
+ it('must be able to deal with spaces in links', () => {
+ cy.get('.EasyMDEContainer').should('be.visible');
+ cy.get('#textarea').should('not.be.visible');
+
+ cy.window().then(($win) => {
+ cy.stub($win, 'prompt').returns('https://example.com?some=very special param');
+ cy.get('button.link').click();
+ });
+ cy.get('.EasyMDEContainer .CodeMirror').contains('[](https://example.com?some=very%20special%20param');
+ cy.get('.EasyMDEContainer .CodeMirror').type('{home}{rightarrow}Link to a website!');
+
+ cy.previewOn();
+
+ cy.get('.EasyMDEContainer .editor-preview').should('contain.html', 'Link to a website!
');
+ });
+});
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index d7e51ad..4927ac8 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -13,3 +13,19 @@ Cypress.Commands.add(
return unquote(before.getPropertyValue(property));
},
);
+
+Cypress.Commands.add('previewOn' , () => {
+ cy.get('.EasyMDEContainer .editor-preview').should('not.be.visible');
+ cy.get('.EasyMDEContainer .editor-toolbar button.preview').should('not.have.class', 'active');
+ cy.get('.EasyMDEContainer .editor-toolbar button.preview').click();
+ cy.get('.EasyMDEContainer .editor-toolbar button.preview').should('have.class', 'active');
+ cy.get('.EasyMDEContainer .editor-preview').should('be.visible');
+});
+
+Cypress.Commands.add('previewOff' , () => {
+ cy.get('.EasyMDEContainer .editor-preview').should('be.visible');
+ cy.get('.EasyMDEContainer .editor-toolbar button.preview').should('have.class', 'active');
+ cy.get('.EasyMDEContainer .editor-toolbar button.preview').click();
+ cy.get('.EasyMDEContainer .editor-toolbar button.preview').should('not.have.class', 'active');
+ cy.get('.EasyMDEContainer .editor-preview').should('not.be.visible');
+});
From d8eae5d74c96e5b5dfa52ac39b92e76de432233b Mon Sep 17 00:00:00 2001
From: Jeroen Akkerman
Date: Mon, 17 Jan 2022 00:06:44 +0100
Subject: [PATCH 7/8] Improve readability of encode/escape functionality
---
src/js/easymde.js | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/src/js/easymde.js b/src/js/easymde.js
index db068ef..dbb0135 100644
--- a/src/js/easymde.js
+++ b/src/js/easymde.js
@@ -844,13 +844,11 @@ function drawLink(editor) {
var options = editor.options;
var url = 'https://';
if (options.promptURLs) {
- url = prompt(options.promptTexts.link, 'https://');
+ url = prompt(options.promptTexts.link, url);
if (!url) {
return false;
}
-
- url = encodeURI(url);
- if (/[()]/.test(url)) url = escapePromptURL(url);
+ url = escapePromptURL(url);
}
_replaceSelection(cm, stat.link, options.insertTexts.link, url);
}
@@ -864,25 +862,21 @@ function drawImage(editor) {
var options = editor.options;
var url = 'https://';
if (options.promptURLs) {
- url = prompt(options.promptTexts.image, 'https://');
+ url = prompt(options.promptTexts.image, url);
if (!url) {
return false;
}
-
- url = encodeURI(url);
- if (/[()]/.test(url)) url = escapePromptURL(url);
+ url = escapePromptURL(url);
}
_replaceSelection(cm, stat.image, options.insertTexts.image, url);
}
/**
- * Escape URLs to prevent breaking up rendered Markdown links
+ * Encode and escape URLs to prevent breaking up rendered Markdown links.
* @param url {string} The url of the link or image
*/
function escapePromptURL(url) {
- url = url.replace(/\(/g,'\\(').replace(/\)/g,'\\)');
-
- return url;
+ return encodeURI(url).replace(/([\\()])/g, '\\$1');
}
/**
From 81ec7780bc462e38755bf03ab52ed8bf797cd3f0 Mon Sep 17 00:00:00 2001
From: Jeroen Akkerman
Date: Mon, 17 Jan 2022 00:09:00 +0100
Subject: [PATCH 8/8] Update changelog
---
CHANGELOG.md | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4090519..a7b979f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,10 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
+## [Unreleased]
+### Fixed
+- URLs with certain characters entered through prompts causing invalid markdown (Thanks to [@Zignature], [#393]).
+
## [2.16.1] - 2022-01-14
### Fixed
- Incorrect initial line and column count in status bar.
@@ -240,6 +243,7 @@ Project forked from [SimpleMDE](https://github.com/sparksuite/simplemde-markdown
[#9]: https://github.com/Ionaru/easy-markdown-editor/issues/9
+[#393]: https://github.com/Ionaru/easy-markdown-editor/pull/393
[#389]: https://github.com/Ionaru/easy-markdown-editor/pull/389
[#388]: https://github.com/Ionaru/easy-markdown-editor/pull/388
[#384]: https://github.com/Ionaru/easy-markdown-editor/pull/384