diff --git a/package-lock.json b/package-lock.json index b190d0df..7672893c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8067,6 +8067,11 @@ "resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.1.tgz", "integrity": "sha1-fzcwdHysyG4v4L+KF6cQ80eRUXo=" }, + "markdown-it-imsize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/markdown-it-imsize/-/markdown-it-imsize-2.0.1.tgz", + "integrity": "sha1-zKBCeQXQUziiR8ucqdloxc3dUXA=" + }, "markdown-it-mark": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-2.0.0.tgz", diff --git a/package.json b/package.json index 22eca173..9d0fd11e 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "markdown-it-deflist": "^2.0.2", "markdown-it-emoji": "^1.3.0", "markdown-it-footnote": "^3.0.1", + "markdown-it-imsize": "^2.0.1", "markdown-it-mark": "^2.0.0", "markdown-it-pandoc-renderer": "1.1.3", "markdown-it-sub": "^1.0.0", diff --git a/src/components/common/markdownHighlighting.scss b/src/components/common/markdownHighlighting.scss index 48e7fa51..128808c5 100644 --- a/src/components/common/markdownHighlighting.scss +++ b/src/components/common/markdownHighlighting.scss @@ -148,6 +148,7 @@ img { max-width: 100%; padding: 0 0.15em; + box-sizing: content-box; } } diff --git a/src/data/defaultFileProperties.yml b/src/data/defaultFileProperties.yml index 4047a108..0f5aa26c 100644 --- a/src/data/defaultFileProperties.yml +++ b/src/data/defaultFileProperties.yml @@ -27,6 +27,7 @@ extensions: #del: true #fence: true #footnote: true + #imgsize: true #linkify: true #mark: true #sub: true diff --git a/src/data/presets.js b/src/data/presets.js index c82c165d..8dd9e173 100644 --- a/src/data/presets.js +++ b/src/data/presets.js @@ -6,6 +6,7 @@ const zero = { del: false, fence: false, footnote: false, + imgsize: false, linkify: false, mark: false, sub: false, @@ -54,6 +55,7 @@ export default { del: true, fence: true, footnote: true, + imgsize: true, linkify: true, mark: true, sub: true, diff --git a/src/extensions/markdownExtension.js b/src/extensions/markdownExtension.js index 7a449b74..0a89c195 100644 --- a/src/extensions/markdownExtension.js +++ b/src/extensions/markdownExtension.js @@ -2,9 +2,10 @@ import Prism from 'prismjs'; import markdownitAbbr from 'markdown-it-abbr'; import markdownitDeflist from 'markdown-it-deflist'; import markdownitFootnote from 'markdown-it-footnote'; +import markdownitMark from 'markdown-it-mark'; +import markdownitImgsize from 'markdown-it-imsize'; import markdownitSub from 'markdown-it-sub'; import markdownitSup from 'markdown-it-sup'; -import markdownitMark from 'markdown-it-mark'; import markdownitTasklist from './libs/markdownItTasklist'; import extensionSvc from '../services/extensionSvc'; @@ -90,6 +91,9 @@ extensionSvc.onInitConverter(0, (markdown, options) => { if (options.footnote) { markdown.use(markdownitFootnote); } + if (options.imgsize) { + markdown.use(markdownitImgsize); + } if (options.mark) { markdown.use(markdownitMark); } diff --git a/src/services/editorSvc.js b/src/services/editorSvc.js index 44a12182..c49d799f 100644 --- a/src/services/editorSvc.js +++ b/src/services/editorSvc.js @@ -416,17 +416,21 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils, const imgCache = Object.create(null); + const hashImgElt = imgElt => `${imgElt.src}:${imgElt.width || -1}:${imgElt.height || -1}`; + const addToImgCache = (imgElt) => { - let entries = imgCache[imgElt.src]; + const hash = hashImgElt(imgElt); + let entries = imgCache[hash]; if (!entries) { entries = []; - imgCache[imgElt.src] = entries; + imgCache[hash] = entries; } entries.push(imgElt); }; - const getFromImgCache = (src) => { - const entries = imgCache[src]; + const getFromImgCache = (imgEltsToCache) => { + const hash = hashImgElt(imgEltsToCache); + const entries = imgCache[hash]; if (!entries) { return null; } @@ -469,6 +473,17 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils, imgElt.style.display = ''; }; imgElt.src = uri; + // Take img size into account + const sizeElt = imgTokenElt.querySelector('.token.cl-size'); + if (sizeElt) { + const match = sizeElt.textContent.match(/=(\d*)x(\d*)/); + if (match[1]) { + imgElt.width = parseInt(match[1], 10); + } + if (match[2]) { + imgElt.height = parseInt(match[2], 10); + } + } imgEltsToCache.push(imgElt); } const imgTokenWrapper = document.createElement('span'); @@ -483,7 +498,7 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils, this.clEditor.highlighter.on('highlighted', () => { imgEltsToCache.forEach((imgElt) => { - const cachedImgElt = getFromImgCache(imgElt.src); + const cachedImgElt = getFromImgCache(imgElt); if (cachedImgElt) { // Found a previously loaded image that has just been released imgElt.parentNode.replaceChild(cachedImgElt, imgElt); diff --git a/src/services/markdownGrammarSvc.js b/src/services/markdownGrammarSvc.js index 8a4ea443..330f3064 100644 --- a/src/services/markdownGrammarSvc.js +++ b/src/services/markdownGrammarSvc.js @@ -277,6 +277,9 @@ export default { }, }, }; + if (options.imgsize) { + rest.img.inside['cl cl-size'] = /=\d*x\d*/; + } rest.link = { pattern: /\[.*?\]\(.+?\)/gm, inside: {