Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,16 @@ Version note: React 15.4.2+ and react-dom 15.4.2+ is required. Antd version at l
render() {
const uploadConfig = {
QINIU_URL: "http://up.qiniu.com", //上传地址,现在暂只支持七牛上传
QINIU_IMG_TOKEN_URL: "http://www.yourServerAddress.mobi/getUptokenOfQiniu.do", //请求图片的token
QINIU_IMG_TOKEN_URL: "http://www.yourServerAddress.mobi/getUptokenOfQiniu.do", //请求图片的token,支持提供一个返回token的函数
QINIU_PFOP: {
url: "http://www.yourServerAddress.mobi/doQiniuPicPersist.do" //七牛持久保存请求地址
},
QINIU_VIDEO_TOKEN_URL: "http://www.yourServerAddress.mobi/getUptokenOfQiniu.do", //请求媒体资源的token
QINIU_FILE_TOKEN_URL: "http://www.yourServerAddress.mobi/getUptokenOfQiniu.do?name=patch", //其他资源的token的获取
QINIU_VIDEO_TOKEN_URL: "http://www.yourServerAddress.mobi/getUptokenOfQiniu.do", //请求媒体资源的token,支持提供一个返回token的函数
QINIU_FILE_TOKEN_URL: "http://www.yourServerAddress.mobi/getUptokenOfQiniu.do?name=patch", //其他资源的token的获取,支持提供一个返回token的函数
QINIU_IMG_DOMAIN_URL: "https://image.yourServerAddress.mobi", //图片文件地址的前缀
QINIU_DOMAIN_VIDEO_URL: "https://video.yourServerAddress.mobi", //视频文件地址的前缀
QINIU_DOMAIN_FILE_URL: "https://static.yourServerAddress.com/", //其他文件地址前缀
QINIU_DOMAIN_FILE_URL: "https://static.yourServerAddress.com/", //其他文件地址前缀,
isGenerateKeyByRandom: false // 上传时是否由编辑器产生随机的key
}
return <LzEditor
active={true}
Expand All @@ -99,6 +100,7 @@ Version note: React 15.4.2+ and react-dom 15.4.2+ is required. Antd version at l
| 配置项 | 类型 | 默认值 | 说明 |
| -- | -- | -- | -- |
| active | bool | false | 有更新时是否刷新 |
| needClearContent | bool | flase | 是否需要清除编辑器里的内容 |
| importContent | string | "" | 编辑器显示内容 |
| cbReceiver | function | null | 编辑器内容更新后的回调函数,此函数接受一个改动后的返回参数值 |
| undoRedo | bool | true | 是否启用撤销恢复功能,默认启用 |
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"dependencies": {
"antd": "^2.8.3",
"draft-js": "^0.10.0",
"draft-js-export-html": "^0.5.4",
"immutable": "^3.8.1",
"js-base64": "^2.1.9",
"lodash": "^4.17.3",
Expand Down
58 changes: 39 additions & 19 deletions src/editor/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import './components.css'
import '../global/supports/resources/system.css';
import { tokenPropTypes } from '../global/propTypes';
// import 'antd/dist/antd.css';
import React, {Component} from 'react';
import ReactDom from 'react-dom';
Expand Down Expand Up @@ -35,7 +36,8 @@ import {
// Affix,
Icon
} from 'antd';
import {stateToHTML,stateFromHTML,stateToMD,stateFromMD} from './utils';
import {stateFromHTML,stateToMD,stateFromMD} from './utils';
import {stateToHTML} from 'draft-js-export-html';

import getSelectedBlocks from './utils/stateUtils/getSelectedBlocks';
import {PRO_COMMON} from '../global/supports/publicDatas';
Expand Down Expand Up @@ -194,26 +196,41 @@ class EditorConcist extends React.Component {
},60000);
} // 此钩子用作编辑时候的回调
componentWillReceiveProps(newProps) {
if (!newProps.active) {
return false;
}
if (newProps.importContent == this.props.importContent) {
return false;
}
const { needClearContent } = newProps;
const ConvertFormatProps = this.props.convertFormat;
let newContent ="";
// console.log("ConvertFormatProps",ConvertFormatProps)
if (ConvertFormatProps==="html") {
newContent = newProps.importContent.replace(/[\s\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]\>/g,">");
if (newContent == "undefined" ||!newContent) {

if (!needClearContent) {
if (!newProps.active) {
return false;
}
if (newProps.importContent == this.props.importContent) {
return false;
}

// console.log("ConvertFormatProps",ConvertFormatProps)
if (ConvertFormatProps==="html") {
newContent = newProps.importContent.replace(/[\s\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]\>/g,">");
if (newContent == "undefined" ||!newContent) {
newContent = "<p>&nbsp;</p>";
}
} else if (ConvertFormatProps==="markdown") {
newContent = newProps.importContent||"";
this.state.tempSouceContent=newContent;
} else if (ConvertFormatProps==="raw") {
newContent = newProps.importContent||"{}";
}
} else {
if (ConvertFormatProps==="html") {
newContent = "<p>&nbsp;</p>";
} else if (ConvertFormatProps==="markdown") {
newContent = "";
this.state.tempSouceContent=newContent;
} else if (ConvertFormatProps==="raw") {
newContent = "{}";
}
} else if (ConvertFormatProps==="markdown") {
newContent = newProps.importContent||"";
this.state.tempSouceContent=newContent;
} else if (ConvertFormatProps==="raw") {
newContent = newProps.importContent||"{}";
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还有个问题, 下面用了this.state.editorState = values; 而不是this.setState({ editorState: values });, 有点没太理解

/*const decorator = new CompositeDecorator([
LinkDecorator,
ImageDecorator,
Expand Down Expand Up @@ -815,6 +832,7 @@ const Media = (props) => {
return media;
};


EditorConcist.propTypes = {
active: React.PropTypes.bool,
importContent: React.PropTypes.string,
Expand All @@ -834,17 +852,18 @@ EditorConcist.propTypes = {
fullScreen: React.PropTypes.bool,
uploadConfig:React.PropTypes.shape({
QINIU_URL: React.PropTypes.string.isRequired,
QINIU_IMG_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_IMG_TOKEN_URL: tokenPropTypes,
QINIU_PFOP:React.PropTypes.shape({
url: React.PropTypes.string.isRequired
}),
QINIU_VIDEO_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_FILE_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_VIDEO_TOKEN_URL: tokenPropTypes,
QINIU_FILE_TOKEN_URL: tokenPropTypes,
QINIU_DOMAIN_IMG_URL: React.PropTypes.string.isRequired,
QINIU_DOMAIN_VIDEO_URL: React.PropTypes.string.isRequired,
QINIU_DOMAIN_FILE_URL: React.PropTypes.string.isRequired
}),
convertFormat: React.PropTypes.oneOf(['html', 'markdown', 'raw']),
needClearContent: React.PropTypes.bool,
}
EditorConcist.defaultProps = {
undoRedo: true,
Expand All @@ -861,6 +880,7 @@ EditorConcist.defaultProps = {
autoSave: true,
fullScreen:true,
convertFormat: 'html',
needClearContent: false,
};
// export default EditorConcist;
module.exports = EditorConcist;
9 changes: 5 additions & 4 deletions src/editor/toolBar/mediaImageUploader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Icon
} from 'antd';
import {UploadImage,GroupUpload} from '../../global/components/businessComponents';
import { tokenPropTypes } from '../../global/propTypes';
import cloneDeep from "lodash/cloneDeep";
/*视频音频图片*/
class ImgStyleControls extends Component {
Expand Down Expand Up @@ -164,7 +165,7 @@ class ImgStyleControls extends Component {
display: "inline",
overflow: "hidden",
position: "absolute"
}}>{this.state.images.map((item, index) => <img style = {{width:"100px"}} src = {
}}>{this.state.images.map((item, index) => <img key={index} style = {{width:"100px"}} src = {
item.url+"?t=10"
}
onError = {
Expand Down Expand Up @@ -213,12 +214,12 @@ ImgStyleControls.propTypes = {
receiveImage: React.PropTypes.func.isRequired,
uploadConfig:React.PropTypes.shape({
QINIU_URL: React.PropTypes.string.isRequired,
QINIU_IMG_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_IMG_TOKEN_URL: tokenPropTypes,
QINIU_PFOP:React.PropTypes.shape({
url: React.PropTypes.string.isRequired
}),
QINIU_VIDEO_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_FILE_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_VIDEO_TOKEN_URL: tokenPropTypes,
QINIU_FILE_TOKEN_URL: tokenPropTypes,
QINIU_DOMAIN_IMG_URL: React.PropTypes.string.isRequired,
QINIU_DOMAIN_VIDEO_URL: React.PropTypes.string.isRequired,
QINIU_DOMAIN_FILE_URL: React.PropTypes.string.isRequired
Expand Down
25 changes: 17 additions & 8 deletions src/global/components/businessComponents/UploadImage.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {Component} from 'react'
import {Upload, Button, Icon, message,Input} from 'antd';
import {PRO_URL, PRO_QINIU, PRO_COMMON} from '../../supports/publicDatas';
import { tokenPropTypes } from '../../../global/propTypes';
import findIndex from "lodash/findIndex";
import isEqual from "lodash/isEqual";
import cloneDeep from "lodash/cloneDeep";
Expand Down Expand Up @@ -207,11 +208,18 @@ class UploadImage extends Component {
if (!token) {
token = PRO_QINIU.checkQiniu.returnToken(this.props.uploadConfig);
}
key = PRO_COMMON.String.RndNum(20)+"."+PRO_COMMON.String.GetFileExtensionName(file.name)[0];
if (this.props.uploadConfig.QINIU_KEY_PREFIX) {
key = this.props.uploadConfig.QINIU_KEY_PREFIX + '/' + key

const isGenerateKeyByRandom = typeof this.props.uploadConfig.isGenerateKeyByRandom === 'undefined' ? true : false;
if (isGenerateKeyByRandom) {
key = PRO_COMMON.String.RndNum(20)+"."+PRO_COMMON.String.GetFileExtensionName(file.name)[0];
if (this.props.uploadConfig.QINIU_KEY_PREFIX) {
key = this.props.uploadConfig.QINIU_KEY_PREFIX + '/' + key
}

return {token,key};
}
return {token,key}

return {token};
},
multiple: properties.isMultiple || false,
beforeUpload: this.beforeUpload.bind(this),
Expand Down Expand Up @@ -256,15 +264,16 @@ UploadImage.propTypes = {
fileList: React.PropTypes.arrayOf(React.PropTypes.shape({url: React.PropTypes.string.isRequired, thumbUrl: React.PropTypes.string, name: React.PropTypes.string})),
uploadConfig:React.PropTypes.shape({
QINIU_URL: React.PropTypes.string.isRequired,
QINIU_IMG_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_IMG_TOKEN_URL: tokenPropTypes,
QINIU_PFOP:React.PropTypes.shape({
url: React.PropTypes.string.isRequired
}),
QINIU_VIDEO_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_FILE_TOKEN_URL: React.PropTypes.string.isRequired,
QINIU_VIDEO_TOKEN_URL: tokenPropTypes,
QINIU_FILE_TOKEN_URL: tokenPropTypes,
QINIU_DOMAIN_IMG_URL: React.PropTypes.string.isRequired,
QINIU_DOMAIN_VIDEO_URL: React.PropTypes.string.isRequired,
QINIU_DOMAIN_FILE_URL: React.PropTypes.string.isRequired
QINIU_DOMAIN_FILE_URL: React.PropTypes.string.isRequired,
isGenerateKeyByRandom: React.PropTypes.bool.isRequired
})
};

Expand Down
3 changes: 3 additions & 0 deletions src/global/propTypes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

export * from './token';

6 changes: 6 additions & 0 deletions src/global/propTypes/token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';

export const tokenPropTypes = React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.func]);



10 changes: 10 additions & 0 deletions src/global/supports/methods/public.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ module.exports = {
url = uploadConfig.QINIU_IMG_TOKEN_URL;
}
//console.log("token_url",url);

if (Object.prototype.toString.call(url) === '[object Function]') {
token = url();

localStorage.setItem("qiniu_" + type + "_token", token);
localStorage.setItem("last_qiniu_token_time_" + type, Date.parse(new Date()) / 1000);

return "";
}

AJAX.requestData({
url: url,
method: 'post',
Expand Down