From dba3201c79bb57507ac4758d9f96b944eb3aa463 Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Thu, 8 Oct 2020 12:19:11 +0300 Subject: [PATCH 1/3] fix cursor preceise positioning when content with images are loaded into editor, show preview only for images on separate lines (not inlines) --- src/css/easymde.css | 2 +- src/js/easymde.js | 82 ++++++++++++++++++++++++++------------------- 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/src/css/easymde.css b/src/css/easymde.css index ddd3c00..355a487 100644 --- a/src/css/easymde.css +++ b/src/css/easymde.css @@ -374,7 +374,7 @@ display: block; } -span[data-img-src]::before{ +span[data-img-src]::after{ content: ''; background-image: var(--bg-image); display: block; diff --git a/src/js/easymde.js b/src/js/easymde.js index 12fd370..3cbac68 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -2084,54 +2084,68 @@ EasyMDE.prototype.render = function (el) { }); } + function calcHeight(naturalWidth, naturalHeight) { + var height; + var viewportWidth = window.getComputedStyle(document.querySelector('.CodeMirror-sizer')).width.replace('px', ''); + if (naturalWidth < viewportWidth) { + height = naturalHeight + 'px'; + } else { + height = (naturalHeight / naturalWidth * 100) + '%'; + } + return height; + } + + var _vm = this; + + + function assignImageBlockAttributes(parentEl, img) { + parentEl.setAttribute('data-img-src', img.url); + parentEl.setAttribute('style', '--bg-image:url('+img.url+');--width:'+img.naturalWidth+'px;--height:'+calcHeight(img.naturalWidth, img.naturalHeight)); + _vm.codemirror.setSize(); + } + function handleImages() { - if (!options.previewImagesInEditor) { + if (options.previewImagesInEditor === false) { return; } - function calcHeight(naturalWidth, naturalHeight) { - var height; - var viewportWidth = window.getComputedStyle(document.querySelector('.CodeMirror-sizer')).width.replace('px', ''); - if (naturalWidth < viewportWidth) { - height = naturalHeight + 'px'; - } else { - height = (naturalHeight / naturalWidth * 100) + '%'; - } - return height; - } - easyMDEContainer.querySelectorAll('.cm-formatting-image').forEach(function(e) { + easyMDEContainer.querySelectorAll('.cm-image-marker').forEach(function(e) { var parentEl = e.parentElement; + if (!parentEl.innerText.match(/^!\[.*?\]\(.*\)/g)) { + // if img pasted on the same line with other text, don't preview, preview only images on separate line + return; + } if (!parentEl.hasAttribute('data-img-src')) { var srcAttr = parentEl.innerText.match('\\((.*)\\)'); // might require better parsing according to markdown spec - if (srcAttr && srcAttr.length >= 2) { - var img = document.createElement('img'); - img.onload = function() { - parentEl.setAttribute('data-img-src', srcAttr[1]); - parentEl.setAttribute('data-img-width', img.naturalWidth); - parentEl.setAttribute('data-img-height', img.naturalHeight); - parentEl.setAttribute('style', '--bg-image:url('+srcAttr[1]+');--width:'+img.naturalWidth+'px;--height:'+calcHeight(img.naturalWidth, img.naturalHeight)); - }; - img.src = srcAttr[1]; + if (!window.EMDEimagesCache) { + window.EMDEimagesCache = {}; } - } else { - // handle resizes case - var src = parentEl.getAttribute('data-img-src'); - var naturalWidth = +parentEl.getAttribute('data-img-width'); - var naturalHeight = +parentEl.getAttribute('data-img-height'); - parentEl.setAttribute('style', '--bg-image:url('+src+');--width:'+naturalWidth+'px;--height:'+calcHeight(naturalWidth, naturalHeight)); - } + + if (srcAttr && srcAttr.length >= 2) { + var keySrc = srcAttr[1]; + + if (! window.EMDEimagesCache[keySrc]) { + var img = document.createElement('img'); + img.onload = function() { + window.EMDEimagesCache[keySrc] = { + naturalWidth: img.naturalWidth, + naturalHeight: img.naturalHeight, + url: keySrc, + }; + assignImageBlockAttributes(parentEl, window.EMDEimagesCache[keySrc]); + }; + img.src = keySrc; + } else { + assignImageBlockAttributes(parentEl, window.EMDEimagesCache[keySrc]); + } + } + } }); } this.codemirror.on('update', function () { handleImages(); }); - this.onWindowResize = function() { - handleImages(); - }; - - window.addEventListener('resize', this.onWindowResize, true); - this.gui.sideBySide = this.createSideBySide(); this._rendered = this.element; From edfeb876530491c783919ae673cbd1bd532d02d2 Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Thu, 8 Oct 2020 12:20:26 +0300 Subject: [PATCH 2/3] previewImagesInEditor doc improve --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c713992..d660258 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ easyMDE.value('New input for **EasyMDE**'); - **hideIcons**: An array of icon names to hide. Can be used to hide specific icons shown by default without completely customizing the toolbar. - **indentWithTabs**: If set to `false`, indent using spaces instead of tabs. Defaults to `true`. - **initialValue**: If set, will customize the initial value of the editor. -- **previewImagesInEditor**: - EasyMDE will show preview of images, `true` by default, use `false` to disable. +- **previewImagesInEditor**: - EasyMDE will show preview of images, `false` by default, preview for images will appear only for images on separate lines. - **insertTexts**: Customize how certain buttons that insert text behave. Takes an array with two elements. The first element will be the text inserted before the cursor or highlight, and the second element will be inserted after. For example, this is the default link value: `["[", "](http://)"]`. - horizontalRule - image From 0c9be85cd729ae37576b0a4c594f1faf200cab43 Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Thu, 8 Oct 2020 13:27:01 +0300 Subject: [PATCH 3/3] fix not option --- src/js/easymde.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 3cbac68..6286381 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -2105,7 +2105,7 @@ EasyMDE.prototype.render = function (el) { } function handleImages() { - if (options.previewImagesInEditor === false) { + if (!options.previewImagesInEditor) { return; }