From 3defeb1f1b44d96a8177cd33b32b841a1f173339 Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Sun, 1 Mar 2020 11:09:33 +0530 Subject: [PATCH] Allow selecting static files in MarkdownEditor (#565) This adds a new button to the MarkdownEditor (with icon `paperclip`). Clicking the button triggers the staticfilepicker modal. On selecting a file the editor gets updated depending on the file extension, If an image file was selected, *Markdown image tag* is inserted else a *Markdown link tag* is inserted. Irrespective of the file-type selected, the injected Markdown includes **the static-file's relative_path enclosed in a Liquid object with Jekyll's `relative_url` filter**. For example, if static-file `assets/logo.png` is selected, then the inserted Markdown will be: ``` ![]({{ 'assets/logo.png' | relative_url }}) ``` --- src/components/MarkdownEditor.js | 56 +++++++++++++++++-- .../__snapshots__/markdowneditor.spec.js.snap | 25 ++++++++- src/components/tests/markdowneditor.spec.js | 37 ++++++++++++ 3 files changed, 113 insertions(+), 5 deletions(-) diff --git a/src/components/MarkdownEditor.js b/src/components/MarkdownEditor.js index aeac362f6..cf0a2736c 100644 --- a/src/components/MarkdownEditor.js +++ b/src/components/MarkdownEditor.js @@ -2,6 +2,8 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import SimpleMDE from 'simplemde'; import hljs from '../utils/highlighter'; +import FilePicker from './FilePicker'; +import { getExtensionFromPath } from '../utils/helpers'; const classNames = [ 'editor-toolbar', @@ -38,6 +40,9 @@ class MarkdownEditor extends Component { opts['renderingConfig'] = { codeSyntaxHighlighting: true, }; + opts['insertTexts'] = { + image: ['![', '](#url#)'], + }; let toolbarIcons = [ 'bold', 'italic', @@ -51,6 +56,12 @@ class MarkdownEditor extends Component { 'link', 'image', 'table', + { + name: 'filepicker', + action: () => this.refs.filepicker.refs.trigger.click(), + className: 'fa fa-paperclip', + title: 'Insert Static File', + }, '|', 'preview', 'side-by-side', @@ -84,11 +95,48 @@ class MarkdownEditor extends Component { } } + // Adapted from an internal helper function within SimpleMDE package. + _replaceSelectedText = (cm, headNTail, url) => { + const startPoint = cm.getCursor('start'); + const endPoint = cm.getCursor('end'); + const text = cm.getSelection(); + + let [head, tail] = headNTail; + if (url) { + tail = tail.replace('#url#', url); + } + + cm.replaceSelection(`${head}${text}${tail}`); + startPoint.ch += head.length; + + if (startPoint !== endPoint) { + endPoint.ch += head.length; + } + + cm.setSelection(startPoint, endPoint); + cm.focus(); + }; + + handleFilePick = path => { + const { codemirror, getState, options } = this.editor; + const { image, link } = options.insertTexts; + const url = `{{ '${path}' | relative_url }}`; + const ext = getExtensionFromPath(path); + + const type = /png|jpg|gif|jpeg|svg|ico/i.test(ext) ? image : link; + this._replaceSelectedText(codemirror, type, url); + }; + render() { - return React.createElement( - 'div', - { ref: 'container' }, - React.createElement('textarea', { ref: 'text' }) + return ( +
+
+ +
+
+