mirror of
https://github.com/strapi/strapi.git
synced 2025-11-11 07:39:16 +00:00
Handle img links!!!!!!!!
This commit is contained in:
parent
534a1099ac
commit
cdc92607d6
@ -6,19 +6,26 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { includes } from 'lodash';
|
||||||
|
|
||||||
const Link = props => {
|
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 (
|
return (
|
||||||
<a
|
<a
|
||||||
href={url}
|
href={url || aHref}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open(url, '_blank');
|
window.open(url || aHref, '_blank');
|
||||||
}}
|
}}
|
||||||
style={{ cursor: 'pointer' }}
|
style={{ cursor: 'pointer' }}
|
||||||
>
|
>
|
||||||
{props.children}
|
{content || props.children}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,13 +6,28 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
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 cn from 'classnames';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty, toArray } from 'lodash';
|
||||||
|
|
||||||
import WysiwygEditor from 'components/WysiwygEditor';
|
import WysiwygEditor from 'components/WysiwygEditor';
|
||||||
import converter from './converter';
|
import converter from './converter';
|
||||||
import { findLinkEntities, findImageEntities, findVideoEntities } from './strategies';
|
import {
|
||||||
|
findAtomicEntities,
|
||||||
|
findLinkEntities,
|
||||||
|
findImageEntities,
|
||||||
|
findVideoEntities,
|
||||||
|
} from './strategies';
|
||||||
|
|
||||||
import Image from './image';
|
import Image from './image';
|
||||||
import Link from './link';
|
import Link from './link';
|
||||||
@ -55,8 +70,72 @@ const decorator = new CompositeDecorator([
|
|||||||
strategy: findVideoEntities,
|
strategy: findVideoEntities,
|
||||||
component: Video,
|
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 {
|
class PreviewWysiwyg extends React.PureComponent {
|
||||||
state = { editorState: EditorState.createEmpty(), isMounted: false };
|
state = { editorState: EditorState.createEmpty(), isMounted: false };
|
||||||
|
|
||||||
@ -101,26 +180,51 @@ class PreviewWysiwyg extends React.PureComponent {
|
|||||||
|
|
||||||
previewHTML = rawContent => {
|
previewHTML = rawContent => {
|
||||||
const initHtml = isEmpty(rawContent) ? '<p></p>' : rawContent;
|
const initHtml = isEmpty(rawContent) ? '<p></p>' : rawContent;
|
||||||
const html = converter.makeHtml(initHtml);
|
const html = new DOMParser().parseFromString(converter.makeHtml(initHtml), 'text/html');
|
||||||
// This action takes a long time
|
toArray(html.querySelectorAll('a')).forEach(aReplacer);
|
||||||
const blocksFromHTML = convertFromHTML(html);
|
|
||||||
|
let blocksFromHTML = convertFromHTML(html.body.innerHTML);
|
||||||
|
|
||||||
// Make sure blocksFromHTML.contentBlocks !== null
|
|
||||||
if (blocksFromHTML.contentBlocks) {
|
if (blocksFromHTML.contentBlocks) {
|
||||||
const contentState = ContentState.createFromBlockArray(
|
blocksFromHTML = blocksFromHTML.contentBlocks.reduce((acc, block) => {
|
||||||
blocksFromHTML.contentBlocks,
|
if (block.getType() === 'blockquote') {
|
||||||
blocksFromHTML.entityMap,
|
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) });
|
return this.setState({ editorState: EditorState.createWithContent(contentState, decorator) });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent errors if value is empty
|
|
||||||
return this.setState({ editorState: EditorState.createEmpty() });
|
return this.setState({ editorState: EditorState.createEmpty() });
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { placeholder } = this.context;
|
const { placeholder } = this.context;
|
||||||
|
// this.previewHTML2(this.props.data);
|
||||||
return (
|
return (
|
||||||
<div className={this.getClassName()}>
|
<div className={this.getClassName()}>
|
||||||
<WysiwygEditor
|
<WysiwygEditor
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
|
||||||
function findLinkEntities(contentBlock, callback, contentState) {
|
function findLinkEntities(contentBlock, callback, contentState) {
|
||||||
contentBlock.findEntityRanges(character => {
|
contentBlock.findEntityRanges(character => {
|
||||||
const entityKey = character.getEntity();
|
const entityKey = character.getEntity();
|
||||||
@ -5,6 +7,13 @@ function findLinkEntities(contentBlock, callback, contentState) {
|
|||||||
}, callback);
|
}, 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) {
|
function findImageEntities(contentBlock, callback, contentState) {
|
||||||
contentBlock.findEntityRanges(character => {
|
contentBlock.findEntityRanges(character => {
|
||||||
const entityKey = character.getEntity();
|
const entityKey = character.getEntity();
|
||||||
@ -23,4 +32,4 @@ function findVideoEntities(contentBlock, cb, contentState) {
|
|||||||
|
|
||||||
const isVideoType = (fileName) => /\.(mp4|mpg|mpeg|mov|avi)$/i.test(fileName);
|
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';
|
import { DEFAULT_INDENTATION } from './constants';
|
||||||
|
|
||||||
export function createNewBlock(text = '', type = 'unstyled', key = genKey()) {
|
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) {
|
export function getNextBlocksList(editorState, startKey) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user