Skip to content
Snippets Groups Projects
Commit 6270e56e authored by Christos's avatar Christos
Browse files

Merge branch 'images' into 'master'

Images

See merge request !235
parents 95997c81 4e37a8b4
No related branches found
No related tags found
1 merge request!235Images
Showing
with 144 additions and 24 deletions
......@@ -2,7 +2,7 @@ export { default as Overlay } from './src/components/Overlay';
export { default as Button } from './src/components/Button';
export { default as icons } from './src/icons/icons';
export { default as TableDropDown } from './src/components/TableDropDown';
export { default as ImageUpload } from './src/components/ImageUpload';
export { default as ImageUpload } from './src/components/images/ImageUpload';
export { default as TitleButton } from './src/components/TitleButton';
export { default as LeftMenuTitle } from './src/components/LeftMenuTitle';
export { default as ToolGroupComponent } from './src/components/ToolGroupComponent';
......
......@@ -3,7 +3,8 @@ import React, { useContext, useRef, useMemo } from 'react';
import { WaxContext } from 'wax-prosemirror-core';
import styled from 'styled-components';
import MenuButton from '../ui/buttons/MenuButton';
import MenuButton from '../../ui/buttons/MenuButton';
import insertImage from './Upload';
const Wrapper = styled.div`
input {
......@@ -13,12 +14,28 @@ const Wrapper = styled.div`
const ImageUpload = ({ item, fileUpload, view }) => {
const {
app,
activeViewId,
view: { main },
} = useContext(WaxContext);
const inputRef = useRef(null);
const handleMouseDown = () => inputRef.current.click();
const placeholderPlugin = app.PmPlugins.get('imagePlaceHolder');
const imageServiceConfig = app.config.get('config.ImageServie');
const handleMouseDown = () => {
if (imageServiceConfig && imageServiceConfig.handleAssetManager) {
insertThroughFileMAnager();
} else {
inputRef.current.click();
}
};
async function insertThroughFileMAnager() {
const handler = imageServiceConfig.handleAssetManager;
const urls = await handler();
insertImage(urls, view, placeholderPlugin);
}
let isDisabled = !item.select(view.state, activeViewId);
......
const findPlaceholder = (state, id, placeholderPlugin) => {
const decos = placeholderPlugin.getState(state);
const found = decos.find(null, null, spec => spec.id === id);
return found.length ? found[0].from : null;
};
const insertImage = (urls, view, placeholderPlugin) => {
for (let i = 0; i < urls.length; i += 1) {
const { state } = view;
const id = {};
const { tr } = state;
if (!tr.selection.empty) tr.deleteSelection();
tr.setMeta(placeholderPlugin, {
add: { id, pos: tr.selection.from },
});
view.dispatch(tr);
const pos = findPlaceholder(view.state, id, placeholderPlugin);
if (pos == null) {
return;
}
view.dispatch(
state.tr
.replaceWith(
pos,
pos,
view.state.schema.nodes.image.create({
src: urls[i],
}),
)
.setMeta(placeholderPlugin, { remove: { id } }),
);
}
};
export default insertImage;
......@@ -9,3 +9,4 @@ export { default as mathPlugin } from './src/math/math-plugin';
export { default as mathSelectPlugin } from './src/math/math-select';
export { default as FindAndReplacePlugin } from './src/findAndReplace/FindAndReplacePlugin';
export { default as PlaceHolderPlugin } from './src/images/placeHolderPlugin';
export { default as captionPlugin } from './src/images/captionPlugin';
import { Decoration, DecorationSet } from 'prosemirror-view';
import { Plugin, TextSelection } from 'prosemirror-state';
const captionPlugin = key =>
new Plugin({
state: {
init() {
return DecorationSet.empty;
},
apply(tr, set) {
console.log('in apply');
},
},
props: {
decorations(state) {
return this.getState(state);
},
},
});
export default captionPlugin;
......@@ -35,6 +35,8 @@ export { default as orderedListNode } from './src/nodes/orderedListNode';
export { default as bulletListNode } from './src/nodes/bulletListNode';
export { default as listItemNode } from './src/nodes/listItemNode';
export { default as subTitleNode } from './src/nodes/subTitleNode';
export { default as figureNode } from './src/nodes/figureNode';
export { default as figureCaptionNode } from './src/nodes/figureNode';
export { default as imageNode } from './src/nodes/imageNode';
export { default as headingNode } from './src/nodes/headingNode';
export { default as blockQuoteNode } from './src/nodes/blockQuoteNode';
......
const figureCaption = {
content: 'inline*',
group: 'figure',
marks: 'strong link',
parseDOM: [{ tag: 'figcaption' }],
toDOM(node) {
return ['figcaption', 0];
},
};
export default figureCaption;
const figure = {
content: 'image* figcaption{0,1}',
group: 'block',
marks: '',
parseDOM: [{ tag: 'figure' }],
toDOM() {
return ['figure', 0];
},
};
export default figure;
import { SchemaHelpers } from 'wax-prosemirror-utilities';
const image = {
inline: true,
// inline: true,
attrs: {
src: {},
alt: { default: null },
title: { default: null },
track: { default: [] },
},
group: 'inline',
group: 'figure',
draggable: true,
parseDOM: [
{
......
import { imageNode } from 'wax-prosemirror-schema';
import { PlaceHolderPlugin } from 'wax-prosemirror-plugins';
import {
imageNode,
figureCaptionNode,
figureNode,
} from 'wax-prosemirror-schema';
import { PlaceHolderPlugin, captionPlugin } from 'wax-prosemirror-plugins';
import Service from '../Service';
import Image from './Image';
const PLUGIN_KEY = 'imagePlaceHolder';
class ImageService extends Service {
name = 'ImageService';
boot() {
this.app.PmPlugins.add(PLUGIN_KEY, PlaceHolderPlugin(PLUGIN_KEY));
this.app.PmPlugins.add(
'imagePlaceHolder',
PlaceHolderPlugin('imagePlaceHolder'),
);
this.app.PmPlugins.add('caption', captionPlugin('caption'));
}
register() {
this.container.bind('Image').to(Image);
const createNode = this.container.get('CreateNode');
createNode({
figure: figureNode,
});
createNode(
{
image: imageNode,
},
{ toWaxSchema: true },
);
createNode({
figcaption: figureCaptionNode,
});
}
}
......
......@@ -15,7 +15,7 @@ export default (view, fileUpload, placeholderPlugin) => file => {
if (!tr.selection.empty) tr.deleteSelection();
tr.setMeta(placeholderPlugin, {
add: { id, pos: tr.selection.from }
add: { id, pos: tr.selection.from },
});
view.dispatch(tr);
......@@ -35,15 +35,15 @@ export default (view, fileUpload, placeholderPlugin) => file => {
pos,
pos,
view.state.schema.nodes.image.create({
src: url
})
src: url,
}),
)
.setMeta(placeholderPlugin, { remove: { id } })
.setMeta(placeholderPlugin, { remove: { id } }),
);
},
() => {
// On failure, just clean up the placeholder
view.dispatch(tr.setMeta(placeholderPlugin, { remove: { id } }));
}
},
);
};
......@@ -2,7 +2,7 @@
import React, { useEffect, useRef, useContext, useMemo } from 'react';
import { filter } from 'lodash';
import { EditorView } from 'prosemirror-view';
import { EditorState, TextSelection } from 'prosemirror-state';
import { EditorState } from 'prosemirror-state';
import { StepMap } from 'prosemirror-transform';
import { baseKeymap } from 'prosemirror-commands';
import { keymap } from 'prosemirror-keymap';
......@@ -19,6 +19,7 @@ export default ({ node, view }) => {
const noteId = node.attrs.id;
let noteView;
let clickInNote = false;
let typing = false;
// eslint-disable-next-line react/destructuring-assignment
const isEditable = context.view.main.props.editable(editable => {
return editable;
......@@ -44,13 +45,9 @@ export default ({ node, view }) => {
// the parent editor is focused.
if (noteView.hasFocus()) noteView.focus();
},
blur: view => {
view.dispatch(
view.state.tr.setSelection(
TextSelection.create(view.state.doc, 0),
),
);
},
},
handleTextInput: (editorView, from, to, text) => {
typing = true;
},
transformPasted: slice => {
return transformPasted(slice, noteView);
......@@ -105,6 +102,12 @@ export default ({ node, view }) => {
context.updateView({}, noteId);
}, 20);
const findReplace = context.app.PmPlugins.get('findAndReplacePlugin');
const matches = findReplace.getState(noteView.state).allMatches;
if (matches.length > 0 && !typing && context.activeViewId === noteId)
context.updateView({}, noteId);
// UNTIL HERE
if (!tr.getMeta('fromOutside')) {
const outerTr = view.state.tr;
const offsetMap = StepMap.offset(noteFound[0].pos + 1);
......@@ -115,7 +118,7 @@ export default ({ node, view }) => {
}
if (outerTr.docChanged)
view.dispatch(outerTr.setMeta('outsideView', 'notes'));
view.dispatch(outerTr.setMeta('outsideView', noteId));
}
};
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment