mirror of
https://github.com/strapi/strapi.git
synced 2025-11-01 18:33:55 +00:00
Handle img links!!!!!!!!
This commit is contained in:
parent
534a1099ac
commit
cdc92607d6
@ -6,19 +6,26 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { includes } from 'lodash';
|
||||
|
||||
const Link = props => {
|
||||
const { url } = props.contentState.getEntity(props.entityKey).getData();
|
||||
const { url, aHref, aInnerHTML } = props.contentState.getEntity(props.entityKey).getData();
|
||||
let content = aInnerHTML;
|
||||
|
||||
if (includes(aInnerHTML, '<img', 'src=')) {
|
||||
const src = aInnerHTML.split('src="')[1].split('" ')[0];
|
||||
content = <img src={src} alt="img" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
href={url}
|
||||
href={url || aHref}
|
||||
onClick={() => {
|
||||
window.open(url, '_blank');
|
||||
window.open(url || aHref, '_blank');
|
||||
}}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
{props.children}
|
||||
{content || props.children}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
@ -6,13 +6,28 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { CompositeDecorator, ContentState, convertFromHTML, EditorState } from 'draft-js';
|
||||
import {
|
||||
CompositeDecorator,
|
||||
ContentState,
|
||||
convertFromHTML,
|
||||
EditorState,
|
||||
ContentBlock,
|
||||
genKey,
|
||||
Entity,
|
||||
CharacterMetadata,
|
||||
} from 'draft-js';
|
||||
import { List, OrderedSet, Repeat, fromJS } from 'immutable';
|
||||
import cn from 'classnames';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { isEmpty, toArray } from 'lodash';
|
||||
|
||||
import WysiwygEditor from 'components/WysiwygEditor';
|
||||
import converter from './converter';
|
||||
import { findLinkEntities, findImageEntities, findVideoEntities } from './strategies';
|
||||
import {
|
||||
findAtomicEntities,
|
||||
findLinkEntities,
|
||||
findImageEntities,
|
||||
findVideoEntities,
|
||||
} from './strategies';
|
||||
|
||||
import Image from './image';
|
||||
import Link from './link';
|
||||
@ -55,8 +70,72 @@ const decorator = new CompositeDecorator([
|
||||
strategy: findVideoEntities,
|
||||
component: Video,
|
||||
},
|
||||
{
|
||||
strategy: findAtomicEntities,
|
||||
component: Link,
|
||||
},
|
||||
]);
|
||||
|
||||
const getBlockSpecForElement = aElement => ({
|
||||
contentType: 'link',
|
||||
aHref: aElement.href,
|
||||
aInnerHTML: aElement.innerHTML,
|
||||
});
|
||||
|
||||
const elementToBlockSpecElement = element => wrapBlockSpec(getBlockSpecForElement(element));
|
||||
|
||||
const wrapBlockSpec = blockSpec => {
|
||||
if (blockSpec == null) {
|
||||
return null;
|
||||
}
|
||||
const tempEl = document.createElement('blockquote');
|
||||
// stringify meta data and insert it as text content of temp HTML element. We will later extract
|
||||
// and parse it.
|
||||
tempEl.innerText = JSON.stringify(blockSpec);
|
||||
return tempEl;
|
||||
};
|
||||
|
||||
const replaceElement = (oldEl, newEl) => {
|
||||
if (!(newEl instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
const parentNode = oldEl.parentNode;
|
||||
return parentNode.replaceChild(newEl, oldEl);
|
||||
};
|
||||
|
||||
const aReplacer = aElement => replaceElement(aElement, elementToBlockSpecElement(aElement));
|
||||
|
||||
const createContentBlock = (blockData = {}) => {
|
||||
const { key, type, text, data, inlineStyles, entityData } = blockData;
|
||||
|
||||
let blockSpec = {
|
||||
type: type !== null && type !== undefined ? type : 'unstyled',
|
||||
text: text !== null && text !== undefined ? text : '',
|
||||
key: key !== null && key !== undefined ? key : genKey(),
|
||||
};
|
||||
|
||||
if (data) {
|
||||
blockSpec.data = fromJS(data);
|
||||
}
|
||||
|
||||
if (inlineStyles || entityData) {
|
||||
let entityKey;
|
||||
if (entityData) {
|
||||
const { type, mutability, data } = entityData;
|
||||
entityKey = Entity.create(type, mutability, data);
|
||||
} else {
|
||||
entityKey = null;
|
||||
}
|
||||
const style = OrderedSet(inlineStyles || ['LINK']);
|
||||
const charData = CharacterMetadata.applyEntity(
|
||||
CharacterMetadata.create({ style, entityKey }),
|
||||
entityKey,
|
||||
);
|
||||
blockSpec.characterList = List(Repeat(charData, text.length));
|
||||
}
|
||||
return new ContentBlock(blockSpec);
|
||||
};
|
||||
|
||||
class PreviewWysiwyg extends React.PureComponent {
|
||||
state = { editorState: EditorState.createEmpty(), isMounted: false };
|
||||
|
||||
@ -101,26 +180,51 @@ class PreviewWysiwyg extends React.PureComponent {
|
||||
|
||||
previewHTML = rawContent => {
|
||||
const initHtml = isEmpty(rawContent) ? '<p></p>' : rawContent;
|
||||
const html = converter.makeHtml(initHtml);
|
||||
// This action takes a long time
|
||||
const blocksFromHTML = convertFromHTML(html);
|
||||
const html = new DOMParser().parseFromString(converter.makeHtml(initHtml), 'text/html');
|
||||
toArray(html.querySelectorAll('a')).forEach(aReplacer);
|
||||
|
||||
let blocksFromHTML = convertFromHTML(html.body.innerHTML);
|
||||
|
||||
// Make sure blocksFromHTML.contentBlocks !== null
|
||||
if (blocksFromHTML.contentBlocks) {
|
||||
const contentState = ContentState.createFromBlockArray(
|
||||
blocksFromHTML.contentBlocks,
|
||||
blocksFromHTML.entityMap,
|
||||
);
|
||||
blocksFromHTML = blocksFromHTML.contentBlocks.reduce((acc, block) => {
|
||||
if (block.getType() === 'blockquote') {
|
||||
try {
|
||||
const { aHref, aInnerHTML } = JSON.parse(block.getText());
|
||||
const entityData = {
|
||||
type: 'LINK',
|
||||
mutability: 'IMMUTABLE',
|
||||
data: {
|
||||
aHref,
|
||||
aInnerHTML,
|
||||
},
|
||||
};
|
||||
|
||||
const blockSpec = Object.assign(
|
||||
{ type: 'atomic', text: ' ', key: block.getKey() },
|
||||
{ entityData },
|
||||
);
|
||||
const atomicBlock = createContentBlock(blockSpec);
|
||||
|
||||
return acc.concat([atomicBlock]);
|
||||
} catch (err) {
|
||||
return acc.concat(block);
|
||||
}
|
||||
}
|
||||
|
||||
return acc.concat(block);
|
||||
}, []);
|
||||
|
||||
const contentState = ContentState.createFromBlockArray(blocksFromHTML);
|
||||
|
||||
return this.setState({ editorState: EditorState.createWithContent(contentState, decorator) });
|
||||
}
|
||||
|
||||
// Prevent errors if value is empty
|
||||
return this.setState({ editorState: EditorState.createEmpty() });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { placeholder } = this.context;
|
||||
|
||||
// this.previewHTML2(this.props.data);
|
||||
return (
|
||||
<div className={this.getClassName()}>
|
||||
<WysiwygEditor
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
function findLinkEntities(contentBlock, callback, contentState) {
|
||||
contentBlock.findEntityRanges(character => {
|
||||
const entityKey = character.getEntity();
|
||||
@ -5,6 +7,13 @@ function findLinkEntities(contentBlock, callback, contentState) {
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function findAtomicEntities(contentBlock, callback, contentState) {
|
||||
contentBlock.findEntityRanges(character => {
|
||||
const entityKey = character.getEntity();
|
||||
return entityKey !== null && contentBlock.getType() === 'atomic';
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function findImageEntities(contentBlock, callback, contentState) {
|
||||
contentBlock.findEntityRanges(character => {
|
||||
const entityKey = character.getEntity();
|
||||
@ -23,4 +32,4 @@ function findVideoEntities(contentBlock, cb, contentState) {
|
||||
|
||||
const isVideoType = (fileName) => /\.(mp4|mpg|mpeg|mov|avi)$/i.test(fileName);
|
||||
|
||||
export { findLinkEntities, findImageEntities, findVideoEntities };
|
||||
export { findAtomicEntities, findLinkEntities, findImageEntities, findVideoEntities };
|
||||
|
||||
@ -9,7 +9,7 @@ import { List } from 'immutable';
|
||||
import { DEFAULT_INDENTATION } from './constants';
|
||||
|
||||
export function createNewBlock(text = '', type = 'unstyled', key = genKey()) {
|
||||
return new ContentBlock({ key, type, text, charaterList: List([]) });
|
||||
return new ContentBlock({ key, type, text, characterList: List([]) });
|
||||
}
|
||||
|
||||
export function getNextBlocksList(editorState, startKey) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user