diff --git a/src/components/ElTiptap.vue b/src/components/ElTiptap.vue index 3f409c0c..65a768d5 100644 --- a/src/components/ElTiptap.vue +++ b/src/components/ElTiptap.vue @@ -138,6 +138,28 @@ export default { } } + .image-view { + display: inline-block; + line-height: 0; + margin: 0 .2rem; + max-width: 100%; + position: relative; + user-select: none; + vertical-align: baseline; + + &--focused { + &::before { + border: 2px solid #b3d8ff;; + bottom: 0; + content: ''; + left: 0; + position: absolute; + right: 0; + top: 0; + } + } + } + hr { margin-top: 20px; margin-bottom: 20px; diff --git a/src/components/MenuBar/ImageUploadCommandButton.vue b/src/components/MenuBar/ImageUploadCommandButton.vue new file mode 100644 index 00000000..8cbb04bb --- /dev/null +++ b/src/components/MenuBar/ImageUploadCommandButton.vue @@ -0,0 +1,95 @@ + + + + + + + + + + + Choose an image file or drag it here + + + + + + + + + diff --git a/src/components/MenuBar/index.vue b/src/components/MenuBar/index.vue index d985d046..1c527d44 100644 --- a/src/components/MenuBar/index.vue +++ b/src/components/MenuBar/index.vue @@ -43,6 +43,10 @@ icon="link" /> + + { + const width = dom.getAttribute('width') || dom.style.width; + const height = dom.getAttribute('height') || dom.style.height; + + return { + src: dom.getAttribute('src'), + title: dom.getAttribute('title'), + alt: dom.getAttribute('alt'), + width: parseInt(width, 10), + height: parseInt(height, 10), + }; + }, + } ], + toDOM: node => ['img', node.attrs], + }; + } + + get view () { + return { + name: 'ImageView', + + template: ` + + + + `, + + props: ['node', 'view', 'getPos', 'selected'], + + methods: { + // https://github.com/scrumpy/tiptap/issues/361#issuecomment-540299541 + handleImageViewClick () { + let tr = this.view.state.tr; + const pos = this.getPos(); + let pos1 = this.view.state.doc.resolve(pos); + let selection = new NodeSelection(pos1); + tr.setSelection(selection); + this.view.dispatch(tr); + }, + }, + }; + } +} diff --git a/src/extensions/index.js b/src/extensions/index.js index d67367cf..962ad63b 100644 --- a/src/extensions/index.js +++ b/src/extensions/index.js @@ -3,6 +3,7 @@ export { default as Paragraph } from './paragraph'; export { default as Heading } from './heading'; export { default as Blockquote } from './blockquote'; export { default as ListItem } from './list_item'; +export { default as Image } from './image'; // extensions export { default as TextAlign } from './text_align'; diff --git a/src/main.js b/src/main.js index 35e26ea9..32fbd331 100644 --- a/src/main.js +++ b/src/main.js @@ -10,12 +10,13 @@ import { DropdownMenu, DropdownItem, MessageBox, + Dialog, + Upload, } from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import App from './App.vue'; import router from './router'; -import './style/index.scss'; Vue.config.productionTip = false; @@ -26,6 +27,8 @@ Vue.use(Tooltip); Vue.use(Dropdown); Vue.use(DropdownMenu); Vue.use(DropdownItem); +Vue.use(Dialog); +Vue.use(Upload); Vue.prototype.$prompt = MessageBox.prompt; diff --git a/src/utils/shared.js b/src/utils/shared.js index 4121fca4..c72508f0 100644 --- a/src/utils/shared.js +++ b/src/utils/shared.js @@ -9,3 +9,14 @@ export function clamp (val, min, max) { } return val; } + +export function readFileDataUrl (file) { + const reader = new FileReader(); + + return new Promise((resolve, reject) => { + reader.onload = readerEvent => resolve(readerEvent.target.result); + reader.onerror = reject; + + reader.readAsDataURL(file); + }); +} diff --git a/src/views/Index.vue b/src/views/Index.vue index 31703578..fdb1d911 100644 --- a/src/views/Index.vue +++ b/src/views/Index.vue @@ -39,6 +39,7 @@ import { Heading, Blockquote, ListItem, + Image, TextAlign, Indent, @@ -72,6 +73,7 @@ export default { new Italic(), new Strike(), new Link(), + new Image(), new Blockquote(), new CodeBlock(), diff --git a/vue.config.js b/vue.config.js index eae8e668..812461ef 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,6 +1,7 @@ const path = require('path'); module.exports = { + runtimeCompiler: true, chainWebpack: config => { config.resolve.alias .set('@', path.resolve(__dirname, 'src'))