├── .babelrc
├── .eslintrc
├── .flowconfig
├── .gitignore
├── .jsbeautifyrc
├── LICENSE
├── README.cn.md
├── README.md
├── build
├── 244e07c1f99aeefcb66fe01d003258a1.ttf
├── 57a86336bae65701daadc7cd36eb7bf5.eot
├── 61dd1f869f150b36c5946f1f9b631ce7.woff
├── 9e74c39d82e9adee5e6424efc94c3e18.svg
├── bundle.js
├── f0e15ca006c92aecf8c223729df02105.svg
└── index.html
├── java_demo
└── getQiniuUptoken.java
├── package.json
├── publish
├── .DS_Store
├── README.md
├── editor
│ ├── components.css
│ ├── config
│ │ └── colorStyleMap.js
│ ├── decorators
│ │ ├── AudioDecorator.js
│ │ ├── AudioSpan.js
│ │ ├── ImageDecorator.js
│ │ ├── ImageSpan.js
│ │ ├── LinkDecorator.js
│ │ ├── VideoDecorator.js
│ │ ├── VideoSpan.js
│ │ ├── decoratorStyle.css
│ │ └── index.js
│ ├── helpers
│ │ ├── combineOrderedStyles.js
│ │ ├── normalizeAttributes.js
│ │ └── styleToCSS.js
│ ├── index.js
│ ├── toolBar
│ │ ├── alignmentControls.js
│ │ ├── autoSave.js
│ │ ├── autoSaveList.js
│ │ ├── blockSelectorControls.js
│ │ ├── blockStyleControls.js
│ │ ├── colorButton.js
│ │ ├── colorControls.js
│ │ ├── cookieControls.js
│ │ ├── index.js
│ │ ├── inlineStyleControls.js
│ │ ├── mediaImageUploader.js
│ │ ├── medioAudioUploader.js
│ │ ├── medioVideoUploader.js
│ │ ├── pasteNoStyleControls.js
│ │ ├── removeStyleControls.js
│ │ ├── styleButton.js
│ │ ├── undoredoControls.js
│ │ └── urlControls.js
│ └── utils
│ │ ├── ExtendedRichUtils.js
│ │ ├── colorConfig.js
│ │ ├── getCurrentlySelectedBlock.js
│ │ ├── index.js
│ │ ├── stateFromElement
│ │ ├── main.js
│ │ └── replaceTextWithMeta.js
│ │ ├── stateFromHTML
│ │ ├── main.js
│ │ └── parseHTML.js
│ │ ├── stateFromMD
│ │ ├── MarkdownParser.js
│ │ └── main.js
│ │ ├── stateToHTML
│ │ └── main.js
│ │ ├── stateToMD
│ │ └── main.js
│ │ └── stateUtils
│ │ ├── Constants.js
│ │ ├── callModifierForSelectedBlocks.js
│ │ ├── combineOrderedStyles.js
│ │ ├── getEntityRanges.js
│ │ ├── getSelectedBlocks.js
│ │ ├── main.js
│ │ ├── normalizeAttributes.js
│ │ ├── selectionContainsEntity.js
│ │ └── styleToCSS.js
├── global
│ ├── components
│ │ ├── businessComponents.js
│ │ └── businessComponents
│ │ │ ├── GroupUpload.js
│ │ │ └── UploadImage.js
│ ├── i18n.js
│ └── supports
│ │ ├── datas
│ │ ├── base.js
│ │ └── url.js
│ │ ├── methods
│ │ ├── Request.js
│ │ ├── common.js
│ │ └── public.js
│ │ ├── publicDatas.js
│ │ └── resources
│ │ ├── blur.svg
│ │ ├── custom.css
│ │ ├── default.less
│ │ ├── default
│ │ ├── demo.css
│ │ ├── demo_fontclass.html
│ │ ├── demo_symbol.html
│ │ ├── demo_unicode.html
│ │ ├── iconfont.css
│ │ ├── iconfont.eot
│ │ ├── iconfont.js
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
│ │ ├── iconfont.css
│ │ ├── system.css
│ │ └── system.less
├── index.js
├── main.js
├── package.json
└── test.js
├── src
├── editor
│ ├── components.css
│ ├── config
│ │ └── colorStyleMap.jsx
│ ├── decorators
│ │ ├── AudioDecorator.jsx
│ │ ├── AudioSpan.jsx
│ │ ├── ImageDecorator.jsx
│ │ ├── ImageSpan.jsx
│ │ ├── LinkDecorator.jsx
│ │ ├── VideoDecorator.jsx
│ │ ├── VideoSpan.jsx
│ │ ├── decoratorStyle.css
│ │ └── index.js
│ ├── helpers
│ │ ├── combineOrderedStyles.js
│ │ ├── normalizeAttributes.js
│ │ └── styleToCSS.js
│ ├── index.jsx
│ ├── toolBar
│ │ ├── alignmentControls.jsx
│ │ ├── autoSave.jsx
│ │ ├── autoSaveList.jsx
│ │ ├── blockSelectorControls.jsx
│ │ ├── blockStyleControls.jsx
│ │ ├── colorButton.jsx
│ │ ├── colorControls.jsx
│ │ ├── cookieControls.jsx
│ │ ├── index.js
│ │ ├── inlineStyleControls.jsx
│ │ ├── mediaImageUploader.jsx
│ │ ├── medioAudioUploader.jsx
│ │ ├── medioVideoUploader.jsx
│ │ ├── pasteNoStyleControls.jsx
│ │ ├── removeStyleControls.jsx
│ │ ├── styleButton.jsx
│ │ ├── undoredoControls.jsx
│ │ └── urlControls.jsx
│ └── utils
│ │ ├── ExtendedRichUtils.js
│ │ ├── colorConfig.js
│ │ ├── getCurrentlySelectedBlock.js
│ │ ├── index.js
│ │ ├── stateFromElement
│ │ ├── main.js
│ │ └── replaceTextWithMeta.js
│ │ ├── stateFromHTML
│ │ ├── main.js
│ │ └── parseHTML.js
│ │ ├── stateFromMD
│ │ ├── MarkdownParser.js
│ │ └── main.js
│ │ ├── stateToHTML
│ │ └── main.js
│ │ ├── stateToMD
│ │ └── main.js
│ │ └── stateUtils
│ │ ├── Constants.js
│ │ ├── callModifierForSelectedBlocks.js
│ │ ├── combineOrderedStyles.js
│ │ ├── getEntityRanges.js
│ │ ├── getSelectedBlocks.js
│ │ ├── main.js
│ │ ├── normalizeAttributes.js
│ │ ├── selectionContainsEntity.js
│ │ └── styleToCSS.js
├── global
│ ├── components
│ │ ├── businessComponents.js
│ │ └── businessComponents
│ │ │ ├── GroupUpload.jsx
│ │ │ └── UploadImage.jsx
│ ├── i18n.js
│ └── supports
│ │ ├── datas
│ │ ├── base.js
│ │ └── url.jsx
│ │ ├── methods
│ │ ├── Request.jsx
│ │ ├── common.jsx
│ │ └── public.jsx
│ │ ├── publicDatas.js
│ │ └── resources
│ │ ├── blur.svg
│ │ ├── custom.css
│ │ ├── customiconfont.less
│ │ ├── default
│ │ ├── iconfont.css
│ │ ├── iconfont.eot
│ │ ├── iconfont.js
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
│ │ ├── iconfont.css
│ │ ├── system.css
│ │ └── system.less
├── index.js
├── main.js
└── test.jsx
├── webpack.config.js
├── webpack.release.config.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "react-hot-loader/babel",
4 | "transform-class-properties"
5 | ],
6 | "presets": [
7 | ["es2015", {"loose" : true}],
8 | "stage-2",
9 | "react"
10 | ],
11 | "env": {
12 | "development": {
13 | "plugins": [
14 | ["react-transform", {
15 | "transforms": [{
16 | "transform": "react-transform-hmr",
17 | "imports": ["react"],
18 | "locals": ["module"]
19 | }, {
20 | "transform": "react-transform-catch-errors",
21 | "imports": ["react", "redbox-react"]
22 | }]
23 | }]
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": [
4 | "airbnb"
5 | ],
6 | "globals": {
7 | "_": false,
8 | "enquire": false,
9 | "Raven": false
10 | },
11 | "env": {
12 | "browser": true,
13 | "node": true
14 | },
15 | "rules": {
16 | "comma-dangle": 0,
17 | "max-len": 0,
18 | "jsx-quotes": [2, "prefer-single"],
19 | "generator-star-spacing": 0,
20 | "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
21 | "import/no-dynamic-require": 0,
22 | "class-methods-use-this": 0,
23 | "function-paren-newline": 0,
24 | "react/jsx-no-bind": 0,
25 | "react/prefer-stateless-function": 0,
26 | "react/jsx-filename-extension": 0,
27 | "react/forbid-prop-types": 0,
28 | "jsx-a11y/anchor-is-valid": 0,
29 | "react/sort-comp": 0,
30 | "prefer-destructuring": 0,
31 | "react/require-default-props": 0,
32 | "import/no-extraneous-dependencies": 0,
33 | "import/extensions": 0,
34 | "import/no-unresolved": 0
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | .*/node_modules/
3 | .*/build/.*
4 | .*/.idea/.*
5 | .*/.git/.*
6 | .*/.global/.*
7 |
8 | [include]
9 | ./src/editor/utils
10 |
11 | [libs]
12 | ./node_modules/flow-bin/
13 |
14 | [options]
15 | module.system=haste
16 | esproposal.class_static_fields=enable
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | dist/*
3 | release/*
4 | node_modules/*
5 | npm-debug.log
6 | npm-debug.log.*
7 | *.ts
8 |
--------------------------------------------------------------------------------
/.jsbeautifyrc:
--------------------------------------------------------------------------------
1 | {
2 | "html": {
3 | "allowed_file_extensions": ["htm", "html", "xhtml", "shtml", "xml", "svg"],
4 | "brace_style": "collapse",
5 | "end_with_newline": false,
6 | "indent_char": " ",
7 | "indent_handlebars": false,
8 | "indent_inner_html": false,
9 | "indent_scripts": "keep",
10 | "indent_size": 2,
11 | "max_preserve_newlines": 0,
12 | "preserve_newlines": true,
13 | "unformatted": ["a", "span", "img", "code", "pre", "sub", "sup", "em", "strong", "b", "i", "u", "strike", "big",
14 | "small", "pre", "h1", "h2", "h3", "h4", "h5", "h6"],
15 | "wrap_line_length": 120
16 | },
17 | "css": {
18 | "allowed_file_extensions": ["css", "scss", "sass", "less"],
19 | "end_with_newline": false,
20 | "indent_char": " ",
21 | "indent_size": 2,
22 | "newline_between_rules": true,
23 | "selector_separator_newline": true
24 | },
25 | "js": {
26 | "allowed_file_extensions": ["js", "jsx", "json", "eslintrc", "jsbeautifyrc"],
27 | "brace_style": "collapse",
28 | "break_chained_methods": false,
29 | "comma_first": false,
30 | "e4x": false,
31 | "end_with_newline": false,
32 | "indent_char": " ",
33 | "indent_level": 0,
34 | "indent_size": 2,
35 | "jslint_happy": false,
36 | "keep_array_indentation": false,
37 | "keep_function_indentation": false,
38 | "max_preserve_newlines": 0,
39 | "preserve_newlines": true,
40 | "space_after_anon_function": false,
41 | "space_before_conditional": false,
42 | "space_in_empty_paren": false,
43 | "space_in_paren": false,
44 | "unescape_strings": false,
45 | "wrap_line_length": 120
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Li Zhen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/build/244e07c1f99aeefcb66fe01d003258a1.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/build/244e07c1f99aeefcb66fe01d003258a1.ttf
--------------------------------------------------------------------------------
/build/57a86336bae65701daadc7cd36eb7bf5.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/build/57a86336bae65701daadc7cd36eb7bf5.eot
--------------------------------------------------------------------------------
/build/61dd1f869f150b36c5946f1f9b631ce7.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/build/61dd1f869f150b36c5946f1f9b631ce7.woff
--------------------------------------------------------------------------------
/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | react-lz-editor demo page
8 |
9 |
10 |
11 | https://github.com/leejaen/react-lz-editor
12 |
13 |
14 |
15 |
16 | react-lz-editor
17 | An open source rich react editor based on draft-Js and ant design, good support for HTML, markdown and Draft Raw format.
18 | 一款支持 HTML\ markdown\ draft Raw 格式的 react 富文本编辑器,基于 draft-Js 和 ant-design 实现。
19 | Install
20 | npm install react-lz-editor --save
21 | Git
22 | git+ssh://git@github.com/leejaen/react-lz-editor.git
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-lz-editor",
3 | "version": "1.0.3",
4 | "description": "An open source react editor based on draft-Js and ant design, good support HTML, markdown and Draft Raw format.",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "webpack",
9 | "typecheck": "flow",
10 | "dev": "webpack-dev-server --port 4000 --devtool eval --progress --colors --hot --content-base build && lessc src/global/supports/resources/system.less src/global/supports/resources/system.css",
11 | "release": "webpack -p --progress --colors --config webpack.release.config.js",
12 | "publish": "babel -d publish/ src/ --no-comments && lessc src/global/supports/resources/system.less publish/global/supports/resources/system.css"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+ssh://git@github.com/leejaen/react-lz-editor.git"
17 | },
18 | "keywords": [
19 | "react-editor",
20 | "draft-js",
21 | "draftjs",
22 | "react-rich-editor",
23 | "react-text-editor",
24 | "react-lz-editor",
25 | "contenteditable",
26 | "richtext",
27 | "editor"
28 | ],
29 | "author": "leejaen@gmail.com",
30 | "license": "ISC",
31 | "bugs": {
32 | "url": "https://github.com/leejaen/react-lz-editor/issues"
33 | },
34 | "homepage": "https://github.com/leejaen/react-lz-editor#readme",
35 | "devDependencies": {
36 | "babel-cli": "^6.6.5",
37 | "babel-loader": "^6.2.4",
38 | "babel-plugin-import": "^1.1.1",
39 | "babel-plugin-transform-class-properties": "^6.19.0",
40 | "babel-preset-es2015": "^6.6.0",
41 | "babel-preset-react": "^6.16.0",
42 | "babel-preset-stage-2": "^6.18.0",
43 | "css-loader": "^0.23.1",
44 | "eslint": "^3.12.2",
45 | "eslint-plugin-react": "^6.8.0",
46 | "file-loader": "^0.8.5",
47 | "flow-bin": "^0.37.4",
48 | "less": "^2.7.2",
49 | "less-loader": "^2.2.3",
50 | "style-loader": "^0.13.1",
51 | "url-loader": "^0.5.7",
52 | "webpack": "^1.12.14",
53 | "webpack-dev-server": "^1.14.1",
54 | "hmacsha1": "^1.0.0",
55 | "md5": "^2.2.1"
56 | },
57 | "dependencies": {
58 | "antd": "^2.8.3",
59 | "draft-js": "^0.10.0",
60 | "immutable": "^3.8.1",
61 | "js-base64": "^2.1.9",
62 | "lodash": "^4.17.3",
63 | "react": "^15.4.2",
64 | "react-dom": "^15.4.2",
65 | "synthetic-dom": "^0.2.1",
66 | "whatwg-fetch": "^2.0.3"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/publish/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/publish/.DS_Store
--------------------------------------------------------------------------------
/publish/README.md:
--------------------------------------------------------------------------------
1 | [中文](https://github.com/leejaen/react-lz-editor/blob/master/README.cn.md)
2 |
3 | # react-lz-editor
4 |
5 | An open source react rich-text editor ( mordern react editor includes media support such as texts, images, videos, audios, links etc. ), development based on Draft-Js and Ant-design, good support html, markdown, draft-raw mode. It's supports multiple languages well(English, Chinese and Russian for now) and welcome you add your language supports.
6 |
7 | ## Live demo
8 |
9 | [react-lz-editor:](https://leejaen.github.io/react-lz-editor/index.html) https://leejaen.github.io/react-lz-editor/index.html
10 |
11 | Disabled media insert feature on demo page, because of there was no online API support for the time being, here is [The server side API demo in java](https://github.com/leejaen/react-lz-editor/blob/master/java_demo/getQiniuUptoken.java) you may want.
12 |
13 | # Install
14 | ```
15 | npm install react-lz-editor --save
16 | OR
17 | yarn add react-lz-editor
18 | ```
19 |
20 | Version note: React 15.4.2+ and react-dom 15.4.2+ is required. Antd version at least from 2.8.3 in your project is recommended.
21 |
22 | # Git
23 | git+ssh://git@github.com/leejaen/react-lz-editor.git
24 |
25 | # Usage & Examples
26 |
27 | [clicking to code example](https://github.com/leejaen/react-lz-editor/blob/master/src/test.jsx)
28 |
29 | ``` js
30 | import React from 'react';
31 | import ReactDOM from 'react-dom';
32 | import LzEditor from './editor/index.jsx'
33 | class Test extends React.Component {
34 | constructor(props) {
35 | super(props);
36 | this.state = {
37 | htmlContent: `Yankees, Peeking at the Red Sox, Will Soon Get an Eyeful
38 | Whenever Girardi stole a glance, there was rarely any good news for the Yankees. While Girardi’s charges were clawing their way to a split of their four-game series against the formidable Indians, the Boston Red Sox were plowing past the rebuilding Chicago White Sox, sweeping four games at Fenway Park.
`,
39 | markdownContent: "## HEAD 2 \n markdown examples \n ``` welcome ```"
40 | responseList: []
41 | }
42 | this.receiveHtml=this.receiveHtml.bind(this);
43 | }
44 | receiveHtml(content) {
45 | console.log("recieved HTML content", content);
46 | this.setState({responseList:[]});
47 | }
48 | render() {
49 | let policy = "";
50 | const uploadProps = {
51 | action: "http://v0.api.upyun.com/devopee",
52 | onChange: this.onChange,
53 | listType: 'picture',
54 | fileList: this.state.responseList,
55 | data: (file) => {
56 |
57 | },
58 | multiple: true,
59 | beforeUpload: this.beforeUpload,
60 | showUploadList: true
61 | }
62 | return (
63 |
64 |
Editor demo 1 (use default html format ):
65 |
66 |
68 |
69 |
Editor demo 2 (use markdown format ):
70 |
71 |
79 |
80 | );
81 | }
82 | }
83 |
84 | ReactDOM.render(
85 | , document.getElementById('test'));
86 |
87 | ```
88 |
89 | 
90 |
91 | # API
92 | | props | type | default | description |
93 | | -- | -- | -- | -- |
94 | | active | bool | false | Is reloading content after changing |
95 | | importContent | string | "" | Editor content value, default to "" |
96 | | lang | string | "" | Editor using language, default to your browser language settings |
97 | | cbReceiver | function | null | `Callback` function, the changed value will be sent to its parameter. |
98 | | undoRedo | bool | true | Enabled `undo and redo` feature, default to true |
99 | | removeStyle | bool | true | Enabled `remove style` feature, default to true |
100 | | pasteNoStyle | bool | true | Enabled `paste plan text` feature, default to true |
101 | | blockStyle | bool | true | Enabled `block style (H1,ol,pre etc.)` feature, default to true |
102 | | alignment | bool | true | Enabled `text alignment` feature, default to true |
103 | | inlineStyle | bool | true | Enabled `inline style (bold, italic, underline etc.)` feature, default to true |
104 | | color | bool | true | Enabled `color text` feature, default to true |
105 | | image | bool | true | Enabled `insert image` feature, default to true |
106 | | video | bool | true | Enabled `insert video` feature, default to true |
107 | | audio | bool | true | Enabled `insert audio` feature, default to true |
108 | | urls | bool | true | Enabled `add hyper link` feature, default to true |
109 | | autoSave | bool | true | Enabled `auto save to draft-box` feature, default to true |
110 | | fullScreen | bool | true | Enabled `full screen` feature, default to true |
111 | | convertFormat | string | "html" | Set support format `(html, markdown, raw)`, default to "html" |
112 | | disabled | bool | false | Disabled editor or not |
113 | | uploadProps | object | null | Customize uploading settings. [API: Antd.Upload](https://ant.design/components/upload/) |
114 |
--------------------------------------------------------------------------------
/publish/editor/components.css:
--------------------------------------------------------------------------------
1 |
2 | .editorHidden{
3 | z-index: 10;
4 | overflow: hidden;
5 | position: relative;
6 | }
7 | .editor_container {
8 | border: 1px solid #E9E9E9;
9 | background-color: #F9F9F9;
10 | padding: 5px;
11 | }
12 |
13 | .editor_top {
14 | height: 30px;
15 | width: 100%;
16 | }
17 |
18 | .editor_middle {
19 | background-color: #FFF;
20 | border: 1px solid #E9E9E9;
21 | box-shadow: 3px 3px 5px #AAA inset;
22 | }
23 |
24 | .editor_bottom {
25 | height: 30px;
26 | width: 100%;
27 | }
28 |
29 | .superFancyBlockquote {
30 | color: #999;
31 | font-style: italic;
32 | text-align: center;
33 | }
34 |
35 | .RichEditor-root {
36 | background: #FFF;
37 | border: 1px solid #DDD;
38 | font-size: 14px;
39 | padding: 15px;
40 | }
41 |
42 | .RichEditor-editor {
43 | border-top: 1px solid #DDD;
44 | cursor: text;
45 | font-size: 16px;
46 | }
47 |
48 | .public-DraftStyleDefault-ul {
49 | list-style: disc;
50 | padding-left: 2.0rem
51 | }
52 |
53 | .public-DraftStyleDefault-ol {
54 | padding-left: 2.0rem;
55 | list-style-type: decimal;
56 | counter-reset: ol-counter;
57 | }
58 |
59 | .public-DraftStyleDefault-ol:before {
60 | content: counter(ol-counter);
61 | counter-increment: ol-counter;
62 | }
63 |
64 | .RichEditor-editor .public-DraftEditorPlaceholder-root,
65 | .RichEditor-editor .public-DraftEditor-content {
66 | margin: 0 -15px -15px;
67 | padding: 15px;
68 | }
69 |
70 | .RichEditor-editor .public-DraftEditor-content {
71 | min-height: 400px;
72 | line-height: initial;
73 | }
74 |
75 | .public-DraftEditor-content>div>* {
76 | margin: 10px 0;
77 | }
78 |
79 | .public-DraftEditor-content pre {
80 | white-space: pre-wrap;
81 | word-wrap: break-word;
82 | }
83 |
84 | .RichEditor-hidePlaceholder .public-DraftEditorPlaceholder-root {
85 | display: none;
86 | }
87 |
88 | .RichEditor-editor .RichEditor-blockquote {
89 | border-left: 5px solid #EEE;
90 | color: #666;
91 | font-family: 'Hoefler Text', 'Georgia', serif;
92 | font-style: italic;
93 | margin: 16px 0;
94 | padding: 10px 20px;
95 | }
96 |
97 | .RichEditor-editor .RichEditor-alignment-left {
98 | text-align: left;
99 | }
100 |
101 | .RichEditor-editor .RichEditor-alignment-center {
102 | text-align: center;
103 | }
104 |
105 | .RichEditor-editor .RichEditor-alignment-right {
106 | text-align: right;
107 | }
108 |
109 | .RichEditor-editor .RichEditor-alignment-justify {
110 | text-align: justify;
111 | }
112 |
113 | .RichEditor-editor .public-DraftStyleDefault-pre {
114 | background-color: rgba(0, 0, 0, 0.05);
115 | font-family: 'Inconsolata', 'Menlo', 'Consolas', monospace;
116 | font-size: 16px;
117 | padding: 20px;
118 | }
119 |
120 | .RichEditor-controls {
121 | font-family: 'Helvetica', sans-serif;
122 | font-size: 14px;
123 | margin-bottom: 5px;
124 | user-select: none;
125 | display: inline;
126 | border-left: 1px solid #EEE;
127 | }
128 |
129 | .RichEditor-controls-split {
130 | padding-right: 20px
131 | }
132 |
133 | .RichEditor-color span {
134 | margin: 0;
135 | width: 16px;
136 | line-height: 28px;
137 | }
138 |
139 | .RichEditor-styleButton {
140 | color: #999;
141 | cursor: pointer;
142 | margin: 0 8px;
143 | padding: 3px 5px !important;
144 | display: inline-block;
145 | position: relative;
146 | margin: 8px 5px;
147 | line-height: 20px;
148 | font-size: 16px;
149 | }
150 | .RichEditor-styleButton.ant-btn.ant-btn-primary.ant-btn-icon-only{
151 | color: #fff;
152 | }
153 |
154 | .RichEditor-styleButton i.anticon {
155 | margin-left: 0px !important;
156 | }
157 | .RichEditor-activeButton {
158 | color: #fff;
159 | border-radius: 5px;
160 | }
161 |
162 | .RichEditor-color {
163 | display: inline-block;
164 | height: 16px;
165 | width: 16px;
166 | overflow: hidden;
167 | top: 3px;
168 | position: relative;
169 | border-radius: 3px;
170 | margin: 0px 5px;
171 | }
172 |
173 | .RichEditor-color-active {}
174 |
175 | .RichEditor-color:nth-child(2n+1) {}
176 |
177 | #text-editor-affix>.ant-affix{background-color:#fff!important;}
178 | .disabled-mask {
179 | background: rgba(200,200,200,0.5);
180 | width: 100%;
181 | height: 100%;
182 | top: 0;
183 | display: block;
184 | position: absolute;
185 | pointer-events: unset;
186 | cursor: not-allowed;
187 | left: 0;
188 | }
189 | .disabled-editor{
190 | filter: grayscale(100%);
191 | }
192 |
--------------------------------------------------------------------------------
/publish/editor/config/colorStyleMap.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var colorStyleMap = {
4 | grapeFruit1: {
5 | color: '#ED5565'
6 | },
7 | grapeFruit2: {
8 | color: '#Da4453'
9 | },
10 | bitterSweet1: {
11 | color: '#fc6e51'
12 | },
13 | bitterSweet2: {
14 | color: '#e9573f'
15 | },
16 | sunFlower1: {
17 | color: '#ffce54'
18 | },
19 | sunFlower2: {
20 | color: '#f6bb42'
21 | },
22 | grass1: {
23 | color: '#a0d468'
24 | },
25 | grass2: {
26 | color: '#bcc152'
27 | },
28 | mint1: {
29 | color: '#48cfad'
30 | },
31 | mint2: {
32 | color: '#37bc9b'
33 | },
34 | aqua1: {
35 | color: '#4fc1e9'
36 | },
37 | aqua2: {
38 | color: '#38afda'
39 | },
40 | blueJeans1: {
41 | color: '#5d9cec'
42 | },
43 | blueJeans2: {
44 | color: '#4a89dc'
45 | },
46 | lavander1: {
47 | color: '#ac92ec'
48 | },
49 | lavander2: {
50 | color: '#967adc'
51 | },
52 | mediumGray1: {
53 | color: '#ccd1d9'
54 | },
55 | mediumGray2: {
56 | color: '#aab2bd'
57 | },
58 | darkGray1: {
59 | color: '#656d78'
60 | },
61 | darkGray2: {
62 | color: '#434a54'
63 | }
64 | };
65 |
66 | module.exports = colorStyleMap;
--------------------------------------------------------------------------------
/publish/editor/decorators/AudioDecorator.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _AudioSpan = require('./AudioSpan');
8 |
9 | var _AudioSpan2 = _interopRequireDefault(_AudioSpan);
10 |
11 | var _draftJs = require('draft-js');
12 |
13 | var _main = require('../utils/stateUtils/main');
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function findAudioEntities(contentBlock, callback) {
18 |
19 | contentBlock.findEntityRanges(function (character) {
20 | var entityKey = character.getEntity();
21 | return entityKey != null && _draftJs.Entity.get(entityKey).getType() === _main.ENTITY_TYPE.AUDIO;
22 | }, callback);
23 | }
24 |
25 | exports.default = {
26 | strategy: findAudioEntities,
27 | component: _AudioSpan2.default
28 | };
--------------------------------------------------------------------------------
/publish/editor/decorators/AudioSpan.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _draftJs = require('draft-js');
14 |
15 | var _decoratorStyle = require('./decoratorStyle.css');
16 |
17 | var _decoratorStyle2 = _interopRequireDefault(_decoratorStyle);
18 |
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20 |
21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22 |
23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
24 |
25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
26 |
27 | var AudioSpan = function (_Component) {
28 | _inherits(AudioSpan, _Component);
29 |
30 | function AudioSpan(props) {
31 | _classCallCheck(this, AudioSpan);
32 |
33 | var _this = _possibleConstructorReturn(this, (AudioSpan.__proto__ || Object.getPrototypeOf(AudioSpan)).call(this, props));
34 |
35 | var entity = _draftJs.Entity.get(_this.props.entityKey);
36 |
37 | var _entity$getData = entity.getData(),
38 | width = _entity$getData.width,
39 | height = _entity$getData.height;
40 |
41 | _this.state = {
42 | width: width,
43 | height: height
44 | };
45 | return _this;
46 | }
47 |
48 | _createClass(AudioSpan, [{
49 | key: 'componentDidMount',
50 | value: function componentDidMount() {
51 | var _this2 = this;
52 |
53 | var _state = this.state,
54 | width = _state.width,
55 | height = _state.height;
56 |
57 | var entity = _draftJs.Entity.get(this.props.entityKey);
58 | var audio = document.createElement('audio');
59 |
60 | var _entity$getData2 = entity.getData(),
61 | src = _entity$getData2.src;
62 |
63 | audio.src = src;
64 | audio.onload = function () {
65 | if (width == null || height == null) {
66 | _this2.setState({ width: audio.width, height: audio.height });
67 | _draftJs.Entity.mergeData(_this2.props.entityKey, {
68 | width: audio.width,
69 | height: audio.height,
70 | originalWidth: audio.width,
71 | originalHeight: audio.height
72 | });
73 | }
74 | };
75 | }
76 | }, {
77 | key: 'render',
78 | value: function render() {
79 | var _state2 = this.state,
80 | width = _state2.width,
81 | height = _state2.height;
82 |
83 | var entity = _draftJs.Entity.get(this.props.entityKey);
84 |
85 | var _entity$getData3 = entity.getData(),
86 | src = _entity$getData3.src;
87 |
88 | var audioStyle = {
89 | verticalAlign: 'bottom',
90 | backgroundImage: 'url("' + src + '")',
91 | backgroundSize: width + 'px ' + height + 'px',
92 | lineHeight: height + 'px',
93 | fontSize: height + 'px',
94 | width: width,
95 | height: height,
96 | letterSpacing: width
97 | };
98 |
99 | return _react2.default.createElement(
100 | 'figure',
101 | { className: 'editor-inline-audio', onClick: this._onClick },
102 | _react2.default.createElement('audio', { controls: true, src: '' + src, className: 'media-audio' })
103 | );
104 | }
105 | }, {
106 | key: '_onClick',
107 | value: function _onClick() {}
108 | }, {
109 | key: '_handleResize',
110 | value: function _handleResize(event, data) {
111 | var _data$size = data.size,
112 | width = _data$size.width,
113 | height = _data$size.height;
114 |
115 | this.setState({ width: width, height: height });
116 | _draftJs.Entity.mergeData(this.props.entityKey, { width: width, height: height });
117 | }
118 | }]);
119 |
120 | return AudioSpan;
121 | }(_react.Component);
122 |
123 | exports.default = AudioSpan;
124 |
125 |
126 | AudioSpan.defaultProps = {
127 | children: null,
128 | entityKey: "",
129 | className: ""
130 | };
--------------------------------------------------------------------------------
/publish/editor/decorators/ImageDecorator.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _ImageSpan = require('./ImageSpan');
8 |
9 | var _ImageSpan2 = _interopRequireDefault(_ImageSpan);
10 |
11 | var _draftJs = require('draft-js');
12 |
13 | var _main = require('../utils/stateUtils/main');
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function findImageEntities(contentBlock, callback) {
18 | contentBlock.findEntityRanges(function (character) {
19 | var entityKey = character.getEntity();
20 | return entityKey != null && _draftJs.Entity.get(entityKey).getType() === _main.ENTITY_TYPE.IMAGE;
21 | }, callback);
22 | }
23 |
24 | exports.default = {
25 | strategy: findImageEntities,
26 | component: _ImageSpan2.default
27 | };
--------------------------------------------------------------------------------
/publish/editor/decorators/LinkDecorator.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _react = require('react');
8 |
9 | var _react2 = _interopRequireDefault(_react);
10 |
11 | var _draftJs = require('draft-js');
12 |
13 | var _main = require('../utils/stateUtils/main');
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function Link(props_) {
18 | var _Entity$get$getData = _draftJs.Entity.get(props_.entityKey).getData(),
19 | url = _Entity$get$getData.url;
20 |
21 | return _react2.default.createElement(
22 | 'a',
23 | { href: url },
24 | props_.children
25 | );
26 | }
27 |
28 | function findLinkEntities(contentBlock, callback) {
29 | contentBlock.findEntityRanges(function (character) {
30 | var entityKey = character.getEntity();
31 | return entityKey != null && _draftJs.Entity.get(entityKey).getType() === _main.ENTITY_TYPE.LINK;
32 | }, callback);
33 | }
34 |
35 | exports.default = {
36 | strategy: findLinkEntities,
37 | component: Link
38 | };
--------------------------------------------------------------------------------
/publish/editor/decorators/VideoDecorator.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _VideoSpan = require('./VideoSpan');
8 |
9 | var _VideoSpan2 = _interopRequireDefault(_VideoSpan);
10 |
11 | var _draftJs = require('draft-js');
12 |
13 | var _main = require('../utils/stateUtils/main');
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function findVideoEntities(contentBlock, callback) {
18 | contentBlock.findEntityRanges(function (character) {
19 | var entityKey = character.getEntity();
20 | return entityKey != null && _draftJs.Entity.get(entityKey).getType() === _main.ENTITY_TYPE.VIDEO;
21 | }, callback);
22 | }
23 |
24 | exports.default = {
25 | strategy: findVideoEntities,
26 | component: _VideoSpan2.default
27 | };
--------------------------------------------------------------------------------
/publish/editor/decorators/VideoSpan.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _draftJs = require('draft-js');
14 |
15 | var _decoratorStyle = require('./decoratorStyle.css');
16 |
17 | var _decoratorStyle2 = _interopRequireDefault(_decoratorStyle);
18 |
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20 |
21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22 |
23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
24 |
25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
26 |
27 | var VideoSpan = function (_Component) {
28 | _inherits(VideoSpan, _Component);
29 |
30 | function VideoSpan(props) {
31 | _classCallCheck(this, VideoSpan);
32 |
33 | var _this = _possibleConstructorReturn(this, (VideoSpan.__proto__ || Object.getPrototypeOf(VideoSpan)).call(this, props));
34 |
35 | var entity = _draftJs.Entity.get(_this.props.entityKey);
36 |
37 | var _entity$getData = entity.getData(),
38 | width = _entity$getData.width,
39 | height = _entity$getData.height;
40 |
41 | _this.state = {
42 | width: width,
43 | height: height
44 | };
45 | return _this;
46 | }
47 |
48 | _createClass(VideoSpan, [{
49 | key: 'componentDidMount',
50 | value: function componentDidMount() {
51 | var _this2 = this;
52 |
53 | var _state = this.state,
54 | width = _state.width,
55 | height = _state.height;
56 |
57 | var entity = _draftJs.Entity.get(this.props.entityKey);
58 | var video = document.createElement('video');
59 |
60 | var _entity$getData2 = entity.getData(),
61 | src = _entity$getData2.src;
62 |
63 | video.src = src;
64 | video.onload = function () {
65 | if (width == null || height == null) {
66 | _this2.setState({ width: video.width, height: video.height });
67 | _draftJs.Entity.mergeData(_this2.props.entityKey, {
68 | width: video.width,
69 | height: video.height,
70 | originalWidth: video.width,
71 | originalHeight: video.height
72 | });
73 | }
74 | };
75 | }
76 | }, {
77 | key: 'render',
78 | value: function render() {
79 | var _state2 = this.state,
80 | width = _state2.width,
81 | height = _state2.height;
82 |
83 | var entity = _draftJs.Entity.get(this.props.entityKey);
84 |
85 | var _entity$getData3 = entity.getData(),
86 | src = _entity$getData3.src;
87 |
88 | var videoStyle = {
89 | verticalAlign: 'bottom',
90 | backgroundImage: 'url("' + src + '")',
91 | backgroundSize: width + 'px ' + height + 'px',
92 | lineHeight: height + 'px',
93 | fontSize: height + 'px',
94 | width: width,
95 | height: height,
96 | letterSpacing: width
97 | };
98 |
99 | return _react2.default.createElement(
100 | 'figure',
101 | { className: 'editor-inline-video', onClick: this._onClick },
102 | _react2.default.createElement('video', { controls: 'controls', src: '' + src, className: 'media-video' })
103 | );
104 | }
105 | }, {
106 | key: '_onClick',
107 | value: function _onClick() {}
108 | }, {
109 | key: '_handleResize',
110 | value: function _handleResize(event, data) {
111 | var _data$size = data.size,
112 | width = _data$size.width,
113 | height = _data$size.height;
114 |
115 | this.setState({ width: width, height: height });
116 | _draftJs.Entity.mergeData(this.props.entityKey, { width: width, height: height });
117 | }
118 | }]);
119 |
120 | return VideoSpan;
121 | }(_react.Component);
122 |
123 | exports.default = VideoSpan;
124 |
125 |
126 | VideoSpan.defaultProps = {
127 | children: null,
128 | entityKey: "",
129 | className: ""
130 | };
--------------------------------------------------------------------------------
/publish/editor/decorators/decoratorStyle.css:
--------------------------------------------------------------------------------
1 | .root {
2 | background-repeat: no-repeat;
3 | display: inline-block;
4 | overflow: hidden;
5 | cursor: pointer;
6 | }
7 |
8 | .resize {
9 | border: 1px dashed #78a300;
10 | position: relative;
11 | max-width: 100%;
12 | display: inline-block;
13 | line-height: 0;
14 | top: -1px;
15 | left: -1px
16 | }
17 |
18 | .resizeHandle {
19 | cursor: nwse-resize;
20 | position: absolute;
21 | z-index: 2;
22 | line-height: 1;
23 | bottom: -4px;
24 | right: -5px;
25 | border: 1px solid white;
26 | background-color: #78a300;
27 | width: 8px;
28 | height: 8px;
29 | }
30 | figure{
31 | text-align: center;
32 | overflow: hidden;
33 | }
34 | figure video {
35 | max-width: 300px;
36 | min-width: 300px;
37 | max-height: 200px;
38 | min-height: 200px;
39 | }
40 | figure img,
41 | figure video,
42 | figure audio {
43 | display: block;
44 | margin: 0 auto;
45 | max-width: 100%;
46 | }
47 |
48 | .editor-inline-image,
49 | .editor-inline-video,
50 | .editor-inline-audio
51 | {
52 | display: inline-block;
53 | overflow: hidden;
54 | cursor: pointer;
55 | width: 100%!important;
56 | }
57 | .editor-inline-image:hover,
58 | .editor-inline-video:hover,
59 | .editor-inline-audio:hover{
60 | background-color:#f7f7f7
61 |
62 | }
63 | .editor-inline-image span,
64 | .editor-inline-video span,
65 | .editor-inline-audio span {
66 | font-size: 0px;
67 | color: rgba(0, 0, 0, 0);
68 | position: absolute;
69 | left: -10000px
70 | }
71 |
--------------------------------------------------------------------------------
/publish/editor/decorators/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = {
4 | LinkDecorator: require("./LinkDecorator"),
5 | ImageDecorator: require("./ImageDecorator"),
6 | VideoDecorator: require("./VideoDecorator"),
7 | AudioDecorator: require("./AudioDecorator")
8 | };
--------------------------------------------------------------------------------
/publish/editor/helpers/combineOrderedStyles.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8 |
9 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
10 |
11 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
12 |
13 | function combineOrderedStyles(customMap, defaults) {
14 | if (customMap == null) {
15 | return defaults;
16 | }
17 |
18 | var _defaults = _slicedToArray(defaults, 2),
19 | defaultStyleMap = _defaults[0],
20 | defaultStyleOrder = _defaults[1];
21 |
22 | var styleMap = _extends({}, defaultStyleMap);
23 | var styleOrder = [].concat(_toConsumableArray(defaultStyleOrder));
24 | var _iteratorNormalCompletion = true;
25 | var _didIteratorError = false;
26 | var _iteratorError = undefined;
27 |
28 | try {
29 | for (var _iterator = Object.keys(customMap)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
30 | var _styleName = _step.value;
31 |
32 | if (defaultStyleMap.hasOwnProperty(_styleName)) {
33 | var defaultStyles = defaultStyleMap[_styleName];
34 | styleMap[_styleName] = _extends({}, defaultStyles, customMap[_styleName]);
35 | } else {
36 | styleMap[_styleName] = customMap[_styleName];
37 | styleOrder.push(_styleName);
38 | }
39 | }
40 | } catch (err) {
41 | _didIteratorError = true;
42 | _iteratorError = err;
43 | } finally {
44 | try {
45 | if (!_iteratorNormalCompletion && _iterator.return) {
46 | _iterator.return();
47 | }
48 | } finally {
49 | if (_didIteratorError) {
50 | throw _iteratorError;
51 | }
52 | }
53 | }
54 |
55 | return [styleMap, styleOrder];
56 | }
57 |
58 | exports.default = combineOrderedStyles;
--------------------------------------------------------------------------------
/publish/editor/helpers/normalizeAttributes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var ATTR_NAME_MAP = {
8 | acceptCharset: 'accept-charset',
9 | className: 'class',
10 | htmlFor: 'for',
11 | httpEquiv: 'http-equiv'
12 | };
13 |
14 | function normalizeAttributes(attributes) {
15 | if (attributes == null) {
16 | return attributes;
17 | }
18 | var normalized = {};
19 | var didNormalize = false;
20 | var _iteratorNormalCompletion = true;
21 | var _didIteratorError = false;
22 | var _iteratorError = undefined;
23 |
24 | try {
25 | for (var _iterator = Object.keys(attributes)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
26 | var name = _step.value;
27 |
28 | var newName = name;
29 | if (ATTR_NAME_MAP.hasOwnProperty(name)) {
30 | newName = ATTR_NAME_MAP[name];
31 | didNormalize = true;
32 | }
33 | normalized[newName] = attributes[name];
34 | }
35 | } catch (err) {
36 | _didIteratorError = true;
37 | _iteratorError = err;
38 | } finally {
39 | try {
40 | if (!_iteratorNormalCompletion && _iterator.return) {
41 | _iterator.return();
42 | }
43 | } finally {
44 | if (_didIteratorError) {
45 | throw _iteratorError;
46 | }
47 | }
48 | }
49 |
50 | return didNormalize ? normalized : attributes;
51 | }
52 |
53 | exports.default = normalizeAttributes;
--------------------------------------------------------------------------------
/publish/editor/helpers/styleToCSS.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _CSSProperty = require('react-dom/lib/CSSProperty');
8 |
9 | var VENDOR_PREFIX = /^(moz|ms|o|webkit)-/;
10 | var NUMERIC_STRING = /^\d+$/;
11 | var UPPERCASE_PATTERN = /([A-Z])/g;
12 |
13 | function processStyleName(name) {
14 | return name.replace(UPPERCASE_PATTERN, '-$1').toLowerCase().replace(VENDOR_PREFIX, '-$1-');
15 | }
16 |
17 | function processStyleValue(name, value) {
18 | var isNumeric = void 0;
19 | if (typeof value === 'string') {
20 | isNumeric = NUMERIC_STRING.test(value);
21 | } else {
22 | isNumeric = true;
23 | value = String(value);
24 | }
25 | if (!isNumeric || value === '0' || _CSSProperty.isUnitlessNumber[name] === true) {
26 | return value;
27 | } else {
28 | return value + 'px';
29 | }
30 | }
31 |
32 | function styleToCSS(styleDescr) {
33 | return Object.keys(styleDescr).map(function (name) {
34 | var styleValue = processStyleValue(name, styleDescr[name]);
35 | var styleName = processStyleName(name);
36 | return styleName + ': ' + styleValue;
37 | }).join('; ');
38 | }
39 |
40 | exports.default = styleToCSS;
--------------------------------------------------------------------------------
/publish/editor/toolBar/alignmentControls.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _react = require("react");
4 |
5 | var _react2 = _interopRequireDefault(_react);
6 |
7 | var _styleButton = require("./styleButton");
8 |
9 | var _styleButton2 = _interopRequireDefault(_styleButton);
10 |
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12 |
13 | var AlignmentControls = function AlignmentControls(props) {
14 | var editorState = props.editorState,
15 | lang = props.lang;
16 |
17 | var selection = editorState.getSelection();
18 | var blockType = editorState.getCurrentContent().getBlockForKey(selection.getStartKey()).getType();
19 | var BLOCK_TYPES = [{
20 | text: lang.alignLeft,
21 | label: "editor_alignment_left",
22 | style: 'left'
23 | }, {
24 | text: lang.alignCenter,
25 | label: "editor_alignment_center",
26 | style: 'center'
27 | }, {
28 | text: lang.alignRight,
29 | label: "editor_alignment_right",
30 | style: 'right'
31 | }, {
32 | text: lang.alignJustify,
33 | label: "editor_alignment_justify",
34 | style: 'justify'
35 | }];
36 | return _react2.default.createElement(
37 | "div",
38 | { className: "RichEditor-controls" },
39 | BLOCK_TYPES.map(function (type, i) {
40 | var button = _react2.default.createElement(_styleButton2.default, {
41 | key: type.style,
42 | text: type.text,
43 | active: type.style === blockType,
44 | label: type.label,
45 | onToggle: props.onToggle,
46 | style: type.style });
47 | return button;
48 | })
49 | );
50 | };
51 | module.exports = AlignmentControls;
--------------------------------------------------------------------------------
/publish/editor/toolBar/autoSave.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4 |
5 | var _react = require("react");
6 |
7 | var _react2 = _interopRequireDefault(_react);
8 |
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10 |
11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12 |
13 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
14 |
15 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
16 |
17 | var AutoSave = function (_Component) {
18 | _inherits(AutoSave, _Component);
19 |
20 | function AutoSave(props) {
21 | _classCallCheck(this, AutoSave);
22 |
23 | return _possibleConstructorReturn(this, (AutoSave.__proto__ || Object.getPrototypeOf(AutoSave)).call(this, props));
24 | }
25 |
26 | _createClass(AutoSave, [{
27 | key: "render",
28 | value: function render() {
29 | return _react2.default.createElement(
30 | "div",
31 | { className: "RichEditor-controls" },
32 | _react2.default.createElement(
33 | "span",
34 | { className: "RichEditor-styleButton", onClick: this.props.onToggle },
35 | this.props.lang.autoSave
36 | )
37 | );
38 | }
39 | }]);
40 |
41 | return AutoSave;
42 | }(_react.Component);
43 |
44 | module.exports = AutoSave;
--------------------------------------------------------------------------------
/publish/editor/toolBar/blockSelectorControls.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 |
5 | var _icon = require('antd/lib/icon');
6 |
7 | var _icon2 = _interopRequireDefault(_icon);
8 |
9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10 |
11 | var _react = require('react');
12 |
13 | var _react2 = _interopRequireDefault(_react);
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18 |
19 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20 |
21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
22 |
23 | var RemoveStyleControls = function (_Component) {
24 | _inherits(RemoveStyleControls, _Component);
25 |
26 | function RemoveStyleControls(props) {
27 | _classCallCheck(this, RemoveStyleControls);
28 |
29 | return _possibleConstructorReturn(this, (RemoveStyleControls.__proto__ || Object.getPrototypeOf(RemoveStyleControls)).call(this, props));
30 | }
31 |
32 | _createClass(RemoveStyleControls, [{
33 | key: 'render',
34 | value: function render() {
35 | var className = 'RichEditor-styleButton';
36 | return _react2.default.createElement(
37 | 'div',
38 | { className: 'RichEditor-controls' },
39 | _react2.default.createElement(
40 | 'span',
41 | { className: className, onClick: this.props.onToggle },
42 | _react2.default.createElement(_icon2.default, { key: 'empty_style', type: 'editor_select_block' })
43 | )
44 | );
45 | }
46 | }]);
47 |
48 | return RemoveStyleControls;
49 | }(_react.Component);
50 |
51 | module.exports = RemoveStyleControls;
--------------------------------------------------------------------------------
/publish/editor/toolBar/blockStyleControls.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _react = require("react");
4 |
5 | var _react2 = _interopRequireDefault(_react);
6 |
7 | var _styleButton = require("./styleButton");
8 |
9 | var _styleButton2 = _interopRequireDefault(_styleButton);
10 |
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12 |
13 | var BlockStyleControls = function BlockStyleControls(props) {
14 | var editorState = props.editorState,
15 | lang = props.lang;
16 |
17 | var selection = editorState.getSelection();
18 | var blockType = editorState.getCurrentContent().getBlockForKey(selection.getStartKey()).getType();
19 | var BLOCK_TYPES = [{
20 | text: lang.H1,
21 | label: "editor_H1",
22 | style: 'header-one'
23 | }, {
24 | text: lang.H2,
25 | label: "editor_H2",
26 | style: 'header-two'
27 | }, {
28 | text: lang.H3,
29 | label: "editor_H3",
30 | style: 'header-three'
31 | }, {
32 | text: lang.H4,
33 | label: "editor_H4",
34 | style: 'header-four'
35 | }, {
36 | text: lang.refs,
37 | label: "editor_refs",
38 | style: 'blockquote'
39 | }, {
40 | text: lang.ul,
41 | label: "editor_ul",
42 | style: 'unordered-list-item'
43 | }, {
44 | text: lang.ol,
45 | label: "editor_ol",
46 | style: 'ordered-list-item'
47 | }, {
48 | text: lang.pre,
49 | label: "editor_pre",
50 | style: 'code-block'
51 | }];
52 | return _react2.default.createElement(
53 | "div",
54 | { className: "RichEditor-controls" },
55 | BLOCK_TYPES.map(function (type, i) {
56 | var button = _react2.default.createElement(_styleButton2.default, {
57 | key: type.style,
58 | text: type.text,
59 | active: type.style === blockType,
60 | label: type.label,
61 | onToggle: props.onToggle,
62 | style: type.style });
63 | return button;
64 | })
65 | );
66 | };
67 | module.exports = BlockStyleControls;
--------------------------------------------------------------------------------
/publish/editor/toolBar/colorButton.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4 |
5 | var _react = require('react');
6 |
7 | var _react2 = _interopRequireDefault(_react);
8 |
9 | var _colorStyleMap = require('../config/colorStyleMap');
10 |
11 | var _colorStyleMap2 = _interopRequireDefault(_colorStyleMap);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18 |
19 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20 |
21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
22 |
23 | var ColorButton = function (_Component) {
24 | _inherits(ColorButton, _Component);
25 |
26 | function ColorButton(props) {
27 | _classCallCheck(this, ColorButton);
28 |
29 | var _this = _possibleConstructorReturn(this, (ColorButton.__proto__ || Object.getPrototypeOf(ColorButton)).call(this, props));
30 |
31 | _this.onToggle = function (e) {
32 | e.preventDefault();
33 | _this.props.onToggle(_this.props.style);
34 | };
35 | return _this;
36 | }
37 |
38 | _createClass(ColorButton, [{
39 | key: 'render',
40 | value: function render() {
41 | var _styles,
42 | _this2 = this;
43 |
44 | var styles = (_styles = {
45 | editor: {
46 | borderTop: '1px solid #ddd',
47 | cursor: 'text',
48 | fontSize: 16,
49 | marginTop: 20,
50 | minHeight: 400,
51 | paddingTop: 20
52 | },
53 | controls: {
54 | fontFamily: '\'Helvetica\', sans-serif',
55 | fontSize: 14,
56 | marginBottom: 10,
57 | userSelect: 'none'
58 | },
59 | ColorButton: {
60 | color: '#999',
61 | cursor: 'pointer',
62 | marginRight: 16,
63 | padding: '2px 0'
64 | },
65 | root: {
66 | fontFamily: '\'Georgia\', serif',
67 | padding: 20,
68 | width: 600
69 | },
70 | buttons: {
71 | marginBottom: 10
72 | },
73 | urlInputContainer: {
74 | marginBottom: 10
75 | },
76 | urlInput: {
77 | fontFamily: '\'Georgia\', serif',
78 | marginRight: 10,
79 | padding: 3
80 | }
81 | }, _defineProperty(_styles, 'editor', {
82 | border: '1px solid #ccc',
83 | cursor: 'text',
84 | minHeight: 80,
85 | padding: 10
86 | }), _defineProperty(_styles, 'button', {
87 | marginTop: 10,
88 | textAlign: 'center'
89 | }), _defineProperty(_styles, 'link', {
90 | color: 'blue',
91 | textDecoration: 'underline'
92 | }), _styles);
93 |
94 | var style = Object.assign({}, styles.ColorButton, this.props.active ? _colorStyleMap2.default[this.props.style] : {});
95 | var className = 'RichEditor-styleButton';
96 | return _react2.default.createElement(
97 | 'div',
98 | { className: 'RichEditor-color' },
99 | _react2.default.createElement(
100 | 'span',
101 | {
102 | className: className,
103 | onClick: this.onToggle,
104 | style: {
105 | backgroundColor: _colorStyleMap2.default[this.props.style].color
106 | } },
107 | this.props.label
108 | ),
109 | function () {
110 | if (!!_this2.props.split) {
111 | return _react2.default.createElement(
112 | 'span',
113 | { className: 'RichEditor-controls-split' },
114 | _this2.props.split
115 | );
116 | }
117 | }()
118 | );
119 | }
120 | }]);
121 |
122 | return ColorButton;
123 | }(_react.Component);
124 |
125 | module.exports = ColorButton;
--------------------------------------------------------------------------------
/publish/editor/toolBar/colorControls.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4 |
5 | var _react = require("react");
6 |
7 | var _react2 = _interopRequireDefault(_react);
8 |
9 | var _colorButton = require("./colorButton");
10 |
11 | var _colorButton2 = _interopRequireDefault(_colorButton);
12 |
13 | var _colorConfig = require("../utils/colorConfig");
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18 |
19 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20 |
21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
22 |
23 | var ColorControls = function (_Component) {
24 | _inherits(ColorControls, _Component);
25 |
26 | function ColorControls(props) {
27 | _classCallCheck(this, ColorControls);
28 |
29 | return _possibleConstructorReturn(this, (ColorControls.__proto__ || Object.getPrototypeOf(ColorControls)).call(this, props));
30 | }
31 |
32 | _createClass(ColorControls, [{
33 | key: "render",
34 | value: function render() {
35 | var _this2 = this;
36 |
37 | var currentStyle = this.props.editorState.getCurrentInlineStyle();
38 | var COLORS = Object.keys(_colorConfig.colorStyleMap).map(function (item) {
39 | return { label: ' ', alias: item, style: item };
40 | });
41 | return _react2.default.createElement(
42 | "div",
43 | { className: "RichEditor-controls", style: {
44 | paddingRight: "20px"
45 | } },
46 | COLORS.map(function (type, i) {
47 | return _react2.default.createElement(_colorButton2.default, {
48 | active: currentStyle.has(type.style),
49 | label: type.label,
50 | onToggle: _this2.props.onToggle,
51 | style: type.style,
52 | key: i,
53 | split: i == COLORS.length - 1 ? "|" : "" });
54 | })
55 | );
56 | }
57 | }]);
58 |
59 | return ColorControls;
60 | }(_react.Component);
61 |
62 | module.exports = ColorControls;
--------------------------------------------------------------------------------
/publish/editor/toolBar/cookieControls.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4 |
5 | var _react = require("react");
6 |
7 | var _react2 = _interopRequireDefault(_react);
8 |
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10 |
11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12 |
13 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
14 |
15 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
16 |
17 | var OpenFull = function (_Component) {
18 | _inherits(OpenFull, _Component);
19 |
20 | function OpenFull(props) {
21 | _classCallCheck(this, OpenFull);
22 |
23 | return _possibleConstructorReturn(this, (OpenFull.__proto__ || Object.getPrototypeOf(OpenFull)).call(this, props));
24 | }
25 |
26 | _createClass(OpenFull, [{
27 | key: "render",
28 | value: function render() {
29 | return _react2.default.createElement(
30 | "div",
31 | { className: "RichEditor-controls" },
32 | _react2.default.createElement(
33 | "span",
34 | { className: "RichEditor-styleButton", onClick: this.props.onToggle },
35 | this.props.coverTitle
36 | )
37 | );
38 | }
39 | }]);
40 |
41 | return OpenFull;
42 | }(_react.Component);
43 |
44 | var AutoSave = function (_Component2) {
45 | _inherits(AutoSave, _Component2);
46 |
47 | function AutoSave(props) {
48 | _classCallCheck(this, AutoSave);
49 |
50 | return _possibleConstructorReturn(this, (AutoSave.__proto__ || Object.getPrototypeOf(AutoSave)).call(this, props));
51 | }
52 |
53 | _createClass(AutoSave, [{
54 | key: "render",
55 | value: function render() {
56 | return _react2.default.createElement(
57 | "div",
58 | { className: "RichEditor-controls" },
59 | _react2.default.createElement(
60 | "span",
61 | { className: "RichEditor-styleButton", onClick: this.props.onToggle },
62 | this.props.lang.autoSave
63 | )
64 | );
65 | }
66 | }]);
67 |
68 | return AutoSave;
69 | }(_react.Component);
70 |
71 | ;
72 |
73 | var SourceEditor = function (_Component3) {
74 | _inherits(SourceEditor, _Component3);
75 |
76 | function SourceEditor(props) {
77 | _classCallCheck(this, SourceEditor);
78 |
79 | return _possibleConstructorReturn(this, (SourceEditor.__proto__ || Object.getPrototypeOf(SourceEditor)).call(this, props));
80 | }
81 |
82 | _createClass(SourceEditor, [{
83 | key: "render",
84 | value: function render() {
85 | return _react2.default.createElement(
86 | "div",
87 | { className: "RichEditor-controls" },
88 | _react2.default.createElement(
89 | "span",
90 | { className: "RichEditor-styleButton", onClick: this.props.onToggle },
91 | this.props.coverTitle
92 | )
93 | );
94 | }
95 | }]);
96 |
97 | return SourceEditor;
98 | }(_react.Component);
99 |
100 | ;
101 | module.exports = {
102 | OpenFull: OpenFull,
103 | AutoSave: AutoSave,
104 | SourceEditor: SourceEditor
105 | };
--------------------------------------------------------------------------------
/publish/editor/toolBar/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = {
4 | ImgStyleControls: require("./mediaImageUploader"),
5 | VideoStyleControls: require("./medioVideoUploader"),
6 | AudioStyleControls: require("./medioAudioUploader"),
7 | AutoSaveControls: require("./autoSaveList"),
8 | BlockStyleControls: require("./BlockStyleControls"),
9 | RemoveStyleControls: require("./removeStyleControls"),
10 | InlineStyleControls: require("./inlineStyleControls"),
11 | ColorControls: require("./colorControls"),
12 | PasteNoStyleControls: require("./pasteNoStyleControls"),
13 | AutoSave: require("./autoSave")
14 | };
--------------------------------------------------------------------------------
/publish/editor/toolBar/inlineStyleControls.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4 |
5 | var _react = require('react');
6 |
7 | var _react2 = _interopRequireDefault(_react);
8 |
9 | var _styleButton = require('./styleButton');
10 |
11 | var _styleButton2 = _interopRequireDefault(_styleButton);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16 |
17 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18 |
19 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
20 |
21 | var InlineStyleControls = function (_Component) {
22 | _inherits(InlineStyleControls, _Component);
23 |
24 | function InlineStyleControls(props) {
25 | _classCallCheck(this, InlineStyleControls);
26 |
27 | return _possibleConstructorReturn(this, (InlineStyleControls.__proto__ || Object.getPrototypeOf(InlineStyleControls)).call(this, props));
28 | }
29 |
30 | _createClass(InlineStyleControls, [{
31 | key: 'render',
32 | value: function render() {
33 | var _props = this.props,
34 | editorState = _props.editorState,
35 | onToggle = _props.onToggle,
36 | lang = _props.lang;
37 |
38 | var INLINE_STYLES = [{
39 | text: lang.textBold,
40 | style: 'BOLD',
41 | label: "editor_b"
42 | }, {
43 | text: lang.textItalic,
44 | style: 'ITALIC',
45 | label: "editor_i"
46 | }, {
47 | text: lang.textUnderline,
48 | style: 'UNDERLINE',
49 | label: "editor_u"
50 | }, {
51 | text: lang.textCode,
52 | style: 'CODE',
53 | label: "editor_e"
54 | }];
55 | var currentStyle = editorState ? editorState.getCurrentInlineStyle() : {};
56 | return _react2.default.createElement(
57 | 'div',
58 | { className: 'RichEditor-controls' },
59 | INLINE_STYLES.map(function (type, i) {
60 | return _react2.default.createElement(_styleButton2.default, {
61 | key: type.style,
62 | text: type.text,
63 | active: currentStyle.has(type.style),
64 | label: type.label,
65 | onToggle: onToggle,
66 | style: type.style });
67 | })
68 | );
69 | }
70 | }]);
71 |
72 | return InlineStyleControls;
73 | }(_react.Component);
74 |
75 | module.exports = InlineStyleControls;
--------------------------------------------------------------------------------
/publish/editor/toolBar/removeStyleControls.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 |
5 | var _popconfirm = require('antd/lib/popconfirm');
6 |
7 | var _popconfirm2 = _interopRequireDefault(_popconfirm);
8 |
9 |
10 |
11 | var _icon = require('antd/lib/icon');
12 |
13 | var _icon2 = _interopRequireDefault(_icon);
14 |
15 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
16 |
17 | var _react = require('react');
18 |
19 | var _react2 = _interopRequireDefault(_react);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
24 |
25 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
26 |
27 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
28 |
29 | var RemoveStyleControls = function (_Component) {
30 | _inherits(RemoveStyleControls, _Component);
31 |
32 | function RemoveStyleControls(props) {
33 | _classCallCheck(this, RemoveStyleControls);
34 |
35 | return _possibleConstructorReturn(this, (RemoveStyleControls.__proto__ || Object.getPrototypeOf(RemoveStyleControls)).call(this, props));
36 | }
37 |
38 | _createClass(RemoveStyleControls, [{
39 | key: 'render',
40 | value: function render() {
41 | var className = 'RichEditor-styleButton';
42 | return _react2.default.createElement(
43 | 'div',
44 | { className: 'RichEditor-controls' },
45 | _react2.default.createElement(
46 | _popconfirm2.default,
47 | { title: this.props.lang.confirmToRemove, onConfirm: this.props.onToggle, okText: this.props.lang.doRemove, cancelText: this.props.lang.doNotRemove },
48 | _react2.default.createElement(
49 | 'span',
50 | { className: className },
51 | _react2.default.createElement(_icon2.default, { key: 'empty_style', type: 'editor_empty_style' })
52 | )
53 | )
54 | );
55 | }
56 | }]);
57 |
58 | return RemoveStyleControls;
59 | }(_react.Component);
60 |
61 | module.exports = RemoveStyleControls;
--------------------------------------------------------------------------------
/publish/editor/toolBar/styleButton.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 |
5 | var _icon = require('antd/lib/icon');
6 |
7 | var _icon2 = _interopRequireDefault(_icon);
8 |
9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10 |
11 | var _react = require('react');
12 |
13 | var _react2 = _interopRequireDefault(_react);
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18 |
19 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20 |
21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
22 |
23 | var StyleButton = function (_React$Component) {
24 | _inherits(StyleButton, _React$Component);
25 |
26 | function StyleButton() {
27 | _classCallCheck(this, StyleButton);
28 |
29 | var _this = _possibleConstructorReturn(this, (StyleButton.__proto__ || Object.getPrototypeOf(StyleButton)).call(this));
30 |
31 | _this.onToggle = function (e) {
32 | e.preventDefault();
33 | _this.props.onToggle(_this.props.style);
34 | };
35 | return _this;
36 | }
37 |
38 | _createClass(StyleButton, [{
39 | key: 'render',
40 | value: function render() {
41 | var _this2 = this;
42 |
43 | var className = 'RichEditor-styleButton';
44 | if (this.props.active) {
45 | className += ' RichEditor-activeButton ant-btn ant-btn-primary ant-btn-icon-only ';
46 | }
47 |
48 | return _react2.default.createElement(
49 | 'span',
50 | null,
51 | _react2.default.createElement(
52 | 'span',
53 | { className: className, onClick: this.onToggle, title: this.props.text },
54 | _react2.default.createElement(_icon2.default, { type: '' + this.props.label })
55 | ),
56 | function () {
57 | if (!!_this2.props.split) {
58 | return _react2.default.createElement(
59 | 'span',
60 | { className: 'RichEditor-controls-split' },
61 | _this2.props.split
62 | );
63 | }
64 | }()
65 | );
66 | }
67 | }]);
68 |
69 | return StyleButton;
70 | }(_react2.default.Component);
71 |
72 | module.exports = StyleButton;
--------------------------------------------------------------------------------
/publish/editor/toolBar/undoredoControls.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 |
5 | var _icon = require('antd/lib/icon');
6 |
7 | var _icon2 = _interopRequireDefault(_icon);
8 |
9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10 |
11 | var _react = require('react');
12 |
13 | var _react2 = _interopRequireDefault(_react);
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18 |
19 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20 |
21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
22 |
23 | var undoRedo = function (_Component) {
24 | _inherits(undoRedo, _Component);
25 |
26 | function undoRedo(props) {
27 | _classCallCheck(this, undoRedo);
28 |
29 | return _possibleConstructorReturn(this, (undoRedo.__proto__ || Object.getPrototypeOf(undoRedo)).call(this, props));
30 | }
31 |
32 | _createClass(undoRedo, [{
33 | key: 'render',
34 | value: function render() {
35 | var _this2 = this;
36 |
37 | var className = 'RichEditor-styleButton';
38 | return _react2.default.createElement(
39 | 'div',
40 | { className: 'RichEditor-controls' },
41 | _react2.default.createElement(
42 | 'span',
43 | { className: 'RichEditor-styleButton', onClick: function onClick() {
44 | return _this2.props.onToggle("undo");
45 | }, title: this.props.lang.undo },
46 | _react2.default.createElement(_icon2.default, { key: '_undo', type: 'editor_undo' })
47 | ),
48 | _react2.default.createElement(
49 | 'span',
50 | { className: 'RichEditor-styleButton', onClick: function onClick() {
51 | return _this2.props.onToggle("redo");
52 | }, title: this.props.lang.redo },
53 | _react2.default.createElement(_icon2.default, { key: '_redo', type: 'editor_redo' })
54 | )
55 | );
56 | }
57 | }]);
58 |
59 | return undoRedo;
60 | }(_react.Component);
61 |
62 | ;
63 | module.exports = undoRedo;
--------------------------------------------------------------------------------
/publish/editor/toolBar/urlControls.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 |
5 | var _icon = require("antd/lib/icon");
6 |
7 | var _icon2 = _interopRequireDefault(_icon);
8 |
9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10 |
11 | var _react = require("react");
12 |
13 | var _react2 = _interopRequireDefault(_react);
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18 |
19 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20 |
21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
22 |
23 | var AddUrl = function (_Component) {
24 | _inherits(AddUrl, _Component);
25 |
26 | function AddUrl(props) {
27 | _classCallCheck(this, AddUrl);
28 |
29 | return _possibleConstructorReturn(this, (AddUrl.__proto__ || Object.getPrototypeOf(AddUrl)).call(this, props));
30 | }
31 |
32 | _createClass(AddUrl, [{
33 | key: "render",
34 | value: function render() {
35 | return _react2.default.createElement(
36 | "div",
37 | { className: "RichEditor-controls" },
38 | _react2.default.createElement(
39 | "span",
40 | { className: "RichEditor-styleButton", onClick: this.props.onToggle, title: this.props.lang.addLink },
41 | _react2.default.createElement(_icon2.default, { type: "editor_link" })
42 | )
43 | );
44 | }
45 | }]);
46 |
47 | return AddUrl;
48 | }(_react.Component);
49 |
50 | var CloseUrl = function (_Component2) {
51 | _inherits(CloseUrl, _Component2);
52 |
53 | function CloseUrl(props) {
54 | _classCallCheck(this, CloseUrl);
55 |
56 | return _possibleConstructorReturn(this, (CloseUrl.__proto__ || Object.getPrototypeOf(CloseUrl)).call(this, props));
57 | }
58 |
59 | _createClass(CloseUrl, [{
60 | key: "render",
61 | value: function render() {
62 | return _react2.default.createElement(
63 | "div",
64 | { className: "RichEditor-controls" },
65 | _react2.default.createElement(
66 | "span",
67 | { className: "RichEditor-styleButton", onClick: this.props.onToggle, title: this.props.lang.removeLink },
68 | _react2.default.createElement(_icon2.default, { type: "editor_unlink" })
69 | )
70 | );
71 | }
72 | }]);
73 |
74 | return CloseUrl;
75 | }(_react.Component);
76 |
77 | module.exports = {
78 | AddUrl: AddUrl,
79 | CloseUrl: CloseUrl
80 | };
--------------------------------------------------------------------------------
/publish/editor/utils/ExtendedRichUtils.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.ALIGNMENT_DATA_KEY = exports.ALIGNMENTS = undefined;
7 |
8 | var _draftJs = require('draft-js');
9 |
10 | var _getCurrentlySelectedBlock = require('./getCurrentlySelectedBlock');
11 |
12 | var _getCurrentlySelectedBlock2 = _interopRequireDefault(_getCurrentlySelectedBlock);
13 |
14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15 |
16 | var ALIGNMENTS = exports.ALIGNMENTS = {
17 | CENTER: 'center',
18 | JUSTIFY: 'justify',
19 | LEFT: 'left',
20 | RIGHT: 'right'
21 | };
22 |
23 | var ALIGNMENT_DATA_KEY = exports.ALIGNMENT_DATA_KEY = 'textAlignment';
24 |
25 | var ExtendedRichUtils = Object.assign({}, _draftJs.RichUtils, {
26 | toggleAlignment: function toggleAlignment(editorState, alignment) {
27 | var _getCurrentlySelected = (0, _getCurrentlySelectedBlock2.default)(editorState),
28 | content = _getCurrentlySelected.content,
29 | currentBlock = _getCurrentlySelected.currentBlock,
30 | hasAtomicBlock = _getCurrentlySelected.hasAtomicBlock,
31 | target = _getCurrentlySelected.target;
32 |
33 | if (hasAtomicBlock) {
34 | return editorState;
35 | }
36 |
37 | var blockData = currentBlock.getData();
38 |
39 | var keyName = blockData.get(ALIGNMENT_DATA_KEY);
40 |
41 | var alignmentToSet = !!blockData && keyName === alignment ? undefined : alignment;
42 |
43 | var alignBlockData = new Map();
44 | alignBlockData.set(ALIGNMENT_DATA_KEY, alignmentToSet);
45 |
46 | var newBlockData = _draftJs.Modifier.setBlockData(content, target, alignBlockData);
47 |
48 | return _draftJs.EditorState.push(editorState, newBlockData, 'change-block-type');
49 | },
50 | splitBlock: function splitBlock(editorState) {
51 | var contentState = _draftJs.Modifier.splitBlock(editorState.getCurrentContent(), editorState.getSelection());
52 | var splitState = _draftJs.EditorState.push(editorState, contentState, 'split-block');
53 |
54 | var _getCurrentlySelected2 = (0, _getCurrentlySelectedBlock2.default)(editorState),
55 | currentBlock = _getCurrentlySelected2.currentBlock;
56 |
57 | var alignment = currentBlock.getData().get(ALIGNMENT_DATA_KEY);
58 | if (alignment) {
59 | return ExtendedRichUtils.toggleAlignment(splitState, alignment);
60 | } else {
61 | return splitState;
62 | }
63 | }
64 | });
65 |
66 | exports.default = ExtendedRichUtils;
--------------------------------------------------------------------------------
/publish/editor/utils/colorConfig.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | colorStyleMap: {
5 | grapeFruit1: {
6 | color: '#ED5565'
7 | },
8 | grapeFruit2: {
9 | color: '#Da4453'
10 | },
11 | bitterSweet1: {
12 | color: '#fc6e51'
13 | },
14 | bitterSweet2: {
15 | color: '#e9573f'
16 | },
17 | sunFlower1: {
18 | color: '#ffce54'
19 | },
20 | sunFlower2: {
21 | color: '#f6bb42'
22 | },
23 | grass1: {
24 | color: '#a0d468'
25 | },
26 | grass2: {
27 | color: '#bcc152'
28 | },
29 | mint1: {
30 | color: '#48cfad'
31 | },
32 | mint2: {
33 | color: '#37bc9b'
34 | },
35 | aqua1: {
36 | color: '#4fc1e9'
37 | },
38 | aqua2: {
39 | color: '#38afda'
40 | },
41 | blueJeans1: {
42 | color: '#5d9cec'
43 | },
44 | blueJeans2: {
45 | color: '#4a89dc'
46 | },
47 | lavander1: {
48 | color: '#ac92ec'
49 | },
50 | lavander2: {
51 | color: '#967adc'
52 | },
53 | mediumGray1: {
54 | color: '#ccd1d9'
55 | },
56 | mediumGray2: {
57 | color: '#aab2bd'
58 | },
59 | darkGray1: {
60 | color: '#656d78'
61 | },
62 | darkGray2: {
63 | color: '#434a54'
64 | }
65 | }
66 | };
--------------------------------------------------------------------------------
/publish/editor/utils/getCurrentlySelectedBlock.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | var getCurrentlySelectedBlock = function getCurrentlySelectedBlock(editorState) {
7 | var selection = editorState.getSelection();
8 | var startKey = selection.getStartKey();
9 | var endKey = selection.getEndKey();
10 | var content = editorState.getCurrentContent();
11 | var target = selection;
12 |
13 | if (startKey !== endKey && selection.getEndOffset() === 0) {
14 | var blockBefore = content.getBlockBefore(endKey);
15 | if (!blockBefore) {
16 | throw new Error('Got unexpected null or undefined');
17 | }
18 |
19 | endKey = blockBefore.getKey();
20 | target = target.merge({
21 | anchorKey: startKey,
22 | anchorOffset: selection.getStartOffset(),
23 | focusKey: endKey,
24 | focusOffset: blockBefore.getLength(),
25 | isBackward: false
26 | });
27 | }
28 |
29 | var hasAtomicBlock = content.getBlockMap().skipWhile(function (_, k) {
30 | return k !== startKey;
31 | }).takeWhile(function (_, k) {
32 | return k !== endKey;
33 | }).some(function (v) {
34 | return v.getType() === 'atomic';
35 | });
36 |
37 | var currentBlock = content.getBlockForKey(startKey);
38 |
39 | return {
40 | content: content,
41 | currentBlock: currentBlock,
42 | hasAtomicBlock: hasAtomicBlock,
43 | target: target
44 | };
45 | };
46 |
47 | exports.default = getCurrentlySelectedBlock;
--------------------------------------------------------------------------------
/publish/editor/utils/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _main = require('./stateFromElement/main');
8 |
9 | Object.defineProperty(exports, 'stateFromElement', {
10 | enumerable: true,
11 | get: function get() {
12 | return _interopRequireDefault(_main).default;
13 | }
14 | });
15 |
16 | var _main2 = require('./stateFromHTML/main');
17 |
18 | Object.defineProperty(exports, 'stateFromHTML', {
19 | enumerable: true,
20 | get: function get() {
21 | return _interopRequireDefault(_main2).default;
22 | }
23 | });
24 |
25 | var _main3 = require('./stateToHTML/main');
26 |
27 | Object.defineProperty(exports, 'stateToHTML', {
28 | enumerable: true,
29 | get: function get() {
30 | return _interopRequireDefault(_main3).default;
31 | }
32 | });
33 |
34 | var _main4 = require('./stateFromMD/main');
35 |
36 | Object.defineProperty(exports, 'stateFromMD', {
37 | enumerable: true,
38 | get: function get() {
39 | return _interopRequireDefault(_main4).default;
40 | }
41 | });
42 |
43 | var _main5 = require('./stateToMD/main');
44 |
45 | Object.defineProperty(exports, 'stateToMD', {
46 | enumerable: true,
47 | get: function get() {
48 | return _interopRequireDefault(_main5).default;
49 | }
50 | });
51 |
52 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
--------------------------------------------------------------------------------
/publish/editor/utils/stateFromElement/replaceTextWithMeta.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = replaceTextWithMeta;
7 | function replaceTextWithMeta(subject, searchText, replaceText) {
8 | var text = subject.text,
9 | characterMeta = subject.characterMeta;
10 |
11 | var searchTextLength = searchText.length;
12 | var replaceTextLength = replaceText.length;
13 | var resultTextParts = [];
14 |
15 | var resultCharMeta = characterMeta.slice(0, 0);
16 | var lastEndIndex = 0;
17 | var index = text.indexOf(searchText);
18 | while (index !== -1) {
19 | resultTextParts.push(text.slice(lastEndIndex, index) + replaceText);
20 | resultCharMeta = resultCharMeta.concat(characterMeta.slice(lastEndIndex, index), repeatSeq(characterMeta.slice(index, index + 1), replaceTextLength));
21 | lastEndIndex = index + searchTextLength;
22 | index = text.indexOf(searchText, lastEndIndex);
23 | }
24 | resultTextParts.push(text.slice(lastEndIndex));
25 | resultCharMeta = resultCharMeta.concat(characterMeta.slice(lastEndIndex));
26 | return { text: resultTextParts.join(''), characterMeta: resultCharMeta };
27 | }
28 |
29 | function repeatSeq(seq, count) {
30 | var result = seq.slice(0, 0);
31 | while (count-- > 0) {
32 | result = result.concat(seq);
33 | }
34 | return result;
35 | }
--------------------------------------------------------------------------------
/publish/editor/utils/stateFromHTML/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = stateFromHTML;
7 |
8 | var _index = require('../index');
9 |
10 | var _parseHTML = require('./parseHTML');
11 |
12 | var _parseHTML2 = _interopRequireDefault(_parseHTML);
13 |
14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15 |
16 | function stateFromHTML(html, options) {
17 | var parser = options == null || options.parser == null ? _parseHTML2.default : options.parser;
18 | var element = parser(html);
19 | return (0, _index.stateFromElement)(element, options);
20 | }
--------------------------------------------------------------------------------
/publish/editor/utils/stateFromHTML/parseHTML.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = parseHTML;
7 | function parseHTML(html) {
8 | var doc = void 0;
9 | if (typeof DOMParser !== 'undefined') {
10 | var parser = new DOMParser();
11 | doc = parser.parseFromString(html, 'text/html');
12 | } else {
13 | doc = document.implementation.createHTMLDocument('');
14 | doc.documentElement.innerHTML = html;
15 | }
16 | return doc.body;
17 | }
--------------------------------------------------------------------------------
/publish/editor/utils/stateFromMD/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = stateFromMarkdown;
7 |
8 | var _MarkdownParser = require('./MarkdownParser');
9 |
10 | var _MarkdownParser2 = _interopRequireDefault(_MarkdownParser);
11 |
12 | var _index = require('../index');
13 |
14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15 |
16 | function stateFromMarkdown(markdown) {
17 | var element = _MarkdownParser2.default.parse(markdown, { getAST: true });
18 | return (0, _index.stateFromElement)(element);
19 | }
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/Constants.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | var BLOCK_TYPE = exports.BLOCK_TYPE = {
7 | UNSTYLED: 'unstyled',
8 | HEADER_ONE: 'header-one',
9 | HEADER_TWO: 'header-two',
10 | HEADER_THREE: 'header-three',
11 | HEADER_FOUR: 'header-four',
12 | HEADER_FIVE: 'header-five',
13 | HEADER_SIX: 'header-six',
14 | UNORDERED_LIST_ITEM: 'unordered-list-item',
15 | ORDERED_LIST_ITEM: 'ordered-list-item',
16 | BLOCKQUOTE: 'blockquote',
17 | PULLQUOTE: 'pullquote',
18 | CODE: 'code-block',
19 | ATOMIC: 'atomic'
20 | };
21 |
22 | var ENTITY_TYPE = exports.ENTITY_TYPE = {
23 | LINK: 'LINK',
24 | IMAGE: 'IMAGE',
25 | VIDEO: 'VIDEO',
26 | AUDIO: 'AUDIO'
27 | };
28 |
29 | var INLINE_STYLE = exports.INLINE_STYLE = {
30 | BOLD: 'BOLD',
31 | CODE: 'CODE',
32 | SPAN: 'SPAN',
33 | ITALIC: 'ITALIC',
34 | STRIKETHROUGH: 'STRIKETHROUGH',
35 | UNDERLINE: 'UNDERLINE'
36 | };
37 |
38 | exports.default = {
39 | BLOCK_TYPE: BLOCK_TYPE,
40 | ENTITY_TYPE: ENTITY_TYPE,
41 | INLINE_STYLE: INLINE_STYLE
42 | };
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/callModifierForSelectedBlocks.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _draftJs = require('draft-js');
8 |
9 | var _getSelectedBlocks = require('./getSelectedBlocks');
10 |
11 | var _getSelectedBlocks2 = _interopRequireDefault(_getSelectedBlocks);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | exports.default = function (editorState, modifier) {
16 | for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
17 | args[_key - 2] = arguments[_key];
18 | }
19 |
20 | var contentState = editorState.getCurrentContent();
21 | var currentSelection = editorState.getSelection();
22 |
23 | var startKey = currentSelection.getStartKey();
24 | var endKey = currentSelection.getEndKey();
25 | var startOffset = currentSelection.getStartOffset();
26 | var endOffset = currentSelection.getEndOffset();
27 |
28 | var isSameBlock = startKey === endKey;
29 | var selectedBlocks = (0, _getSelectedBlocks2.default)(contentState, startKey, endKey);
30 |
31 | var finalEditorState = editorState;
32 | selectedBlocks.forEach(function (block) {
33 | var currentBlockKey = block.getKey();
34 | var selectionStart = startOffset;
35 | var selectionEnd = endOffset;
36 |
37 | if (currentBlockKey === startKey) {
38 | selectionStart = startOffset;
39 | selectionEnd = isSameBlock ? endOffset : block.getText().length;
40 | } else if (currentBlockKey === endKey) {
41 | selectionStart = isSameBlock ? startOffset : 0;
42 | selectionEnd = endOffset;
43 | } else {
44 | selectionStart = 0;
45 | selectionEnd = block.getText().length;
46 | }
47 |
48 | var selection = new _draftJs.SelectionState({
49 | anchorKey: currentBlockKey,
50 | anchorOffset: selectionStart,
51 | focusKey: currentBlockKey,
52 | focusOffset: selectionEnd
53 | });
54 |
55 | finalEditorState = modifier.apply(undefined, [finalEditorState, selection].concat(args));
56 | });
57 |
58 | return _draftJs.EditorState.forceSelection(finalEditorState, currentSelection);
59 | };
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/combineOrderedStyles.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
8 |
9 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
10 |
11 | function combineOrderedStyles(customMap, defaults) {
12 | if (customMap == null) {
13 | return defaults;
14 | }
15 |
16 | var _defaults = _slicedToArray(defaults, 2),
17 | defaultStyleMap = _defaults[0],
18 | defaultStyleOrder = _defaults[1];
19 |
20 | var styleMap = Object.assign({}, defaultStyleMap);
21 | var styleOrder = [].concat(_toConsumableArray(defaultStyleOrder));
22 | var _iteratorNormalCompletion = true;
23 | var _didIteratorError = false;
24 | var _iteratorError = undefined;
25 |
26 | try {
27 | for (var _iterator = Object.keys(customMap)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
28 | var _styleName = _step.value;
29 |
30 | if (defaultStyleMap.hasOwnProperty(_styleName)) {
31 | var defaultStyles = defaultStyleMap[_styleName];
32 | styleMap[_styleName] = Object.assign({}, defaultStyles, customMap[_styleName]);
33 | } else {
34 | styleMap[_styleName] = customMap[_styleName];
35 | styleOrder.push(_styleName);
36 | }
37 | }
38 | } catch (err) {
39 | _didIteratorError = true;
40 | _iteratorError = err;
41 | } finally {
42 | try {
43 | if (!_iteratorNormalCompletion && _iterator.return) {
44 | _iterator.return();
45 | }
46 | } finally {
47 | if (_didIteratorError) {
48 | throw _iteratorError;
49 | }
50 | }
51 | }
52 |
53 | return [styleMap, styleOrder];
54 | }
55 |
56 | exports.default = combineOrderedStyles;
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/getEntityRanges.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.EMPTY_SET = undefined;
7 | exports.default = getEntityRanges;
8 |
9 | var _immutable = require('immutable');
10 |
11 | var EMPTY_SET = exports.EMPTY_SET = new _immutable.OrderedSet();
12 |
13 | function getEntityRanges(text, charMetaList) {
14 | var charEntity = null;
15 | var prevCharEntity = null;
16 | var ranges = [];
17 | var rangeStart = 0;
18 | for (var i = 0, len = text.length; i < len; i++) {
19 | prevCharEntity = charEntity;
20 | var meta = charMetaList.get(i);
21 | charEntity = meta ? meta.getEntity() : null;
22 | if (i > 0 && charEntity !== prevCharEntity) {
23 | ranges.push([prevCharEntity, getStyleRanges(text.slice(rangeStart, i), charMetaList.slice(rangeStart, i))]);
24 | rangeStart = i;
25 | }
26 | }
27 | ranges.push([charEntity, getStyleRanges(text.slice(rangeStart), charMetaList.slice(rangeStart))]);
28 | return ranges;
29 | }
30 |
31 | function getStyleRanges(text, charMetaList) {
32 | var charStyle = EMPTY_SET;
33 | var prevCharStyle = EMPTY_SET;
34 | var ranges = [];
35 | var rangeStart = 0;
36 | for (var i = 0, len = text.length; i < len; i++) {
37 | prevCharStyle = charStyle;
38 | var meta = charMetaList.get(i);
39 | charStyle = meta ? meta.getStyle() : EMPTY_SET;
40 | if (i > 0 && !(0, _immutable.is)(charStyle, prevCharStyle)) {
41 | ranges.push([text.slice(rangeStart, i), prevCharStyle]);
42 | rangeStart = i;
43 | }
44 | }
45 | ranges.push([text.slice(rangeStart), charStyle]);
46 | return ranges;
47 | }
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/getSelectedBlocks.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | exports.default = function (contentState, anchorKey, focusKey) {
8 | var isSameBlock = anchorKey === focusKey;
9 | var startingBlock = contentState.getBlockForKey(anchorKey);
10 |
11 | if (!startingBlock) {
12 | return [];
13 | }
14 |
15 | var selectedBlocks = [startingBlock];
16 |
17 | if (!isSameBlock) {
18 | var blockKey = anchorKey;
19 |
20 | while (blockKey !== focusKey) {
21 | var nextBlock = contentState.getBlockAfter(blockKey);
22 |
23 | if (!nextBlock) {
24 | selectedBlocks = [];
25 | break;
26 | }
27 |
28 | selectedBlocks.push(nextBlock);
29 | blockKey = nextBlock.getKey();
30 | }
31 | }
32 |
33 | return selectedBlocks;
34 | };
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _Constants = require('./Constants');
8 |
9 | Object.keys(_Constants).forEach(function (key) {
10 | if (key === "default" || key === "__esModule") return;
11 | Object.defineProperty(exports, key, {
12 | enumerable: true,
13 | get: function get() {
14 | return _Constants[key];
15 | }
16 | });
17 | });
18 | Object.defineProperty(exports, 'Constants', {
19 | enumerable: true,
20 | get: function get() {
21 | return _interopRequireDefault(_Constants).default;
22 | }
23 | });
24 |
25 | var _getEntityRanges = require('./getEntityRanges');
26 |
27 | Object.defineProperty(exports, 'getEntityRanges', {
28 | enumerable: true,
29 | get: function get() {
30 | return _interopRequireDefault(_getEntityRanges).default;
31 | }
32 | });
33 |
34 | var _getSelectedBlocks = require('./getSelectedBlocks');
35 |
36 | Object.defineProperty(exports, 'getSelectedBlocks', {
37 | enumerable: true,
38 | get: function get() {
39 | return _interopRequireDefault(_getSelectedBlocks).default;
40 | }
41 | });
42 |
43 | var _selectionContainsEntity = require('./selectionContainsEntity');
44 |
45 | Object.defineProperty(exports, 'selectionContainsEntity', {
46 | enumerable: true,
47 | get: function get() {
48 | return _interopRequireDefault(_selectionContainsEntity).default;
49 | }
50 | });
51 |
52 | var _callModifierForSelectedBlocks = require('./callModifierForSelectedBlocks');
53 |
54 | Object.defineProperty(exports, 'callModifierForSelectedBlocks', {
55 | enumerable: true,
56 | get: function get() {
57 | return _interopRequireDefault(_callModifierForSelectedBlocks).default;
58 | }
59 | });
60 |
61 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/normalizeAttributes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var ATTR_NAME_MAP = {
8 | acceptCharset: 'accept-charset',
9 | className: 'class',
10 | htmlFor: 'for',
11 | httpEquiv: 'http-equiv'
12 | };
13 |
14 | function normalizeAttributes(attributes) {
15 | if (attributes == null) {
16 | return attributes;
17 | }
18 | var normalized = {};
19 | var didNormalize = false;
20 | var _iteratorNormalCompletion = true;
21 | var _didIteratorError = false;
22 | var _iteratorError = undefined;
23 |
24 | try {
25 | for (var _iterator = Object.keys(attributes)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
26 | var name = _step.value;
27 |
28 | var newName = name;
29 | if (ATTR_NAME_MAP.hasOwnProperty(name)) {
30 | newName = ATTR_NAME_MAP[name];
31 | didNormalize = true;
32 | }
33 | normalized[newName] = attributes[name];
34 | }
35 | } catch (err) {
36 | _didIteratorError = true;
37 | _iteratorError = err;
38 | } finally {
39 | try {
40 | if (!_iteratorNormalCompletion && _iterator.return) {
41 | _iterator.return();
42 | }
43 | } finally {
44 | if (_didIteratorError) {
45 | throw _iteratorError;
46 | }
47 | }
48 | }
49 |
50 | return didNormalize ? normalized : attributes;
51 | }
52 |
53 | exports.default = normalizeAttributes;
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/selectionContainsEntity.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _getSelectedBlocks = require('./getSelectedBlocks');
8 |
9 | var _getSelectedBlocks2 = _interopRequireDefault(_getSelectedBlocks);
10 |
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12 |
13 | exports.default = function (strategy) {
14 | return function (editorState, selection) {
15 | var contentState = editorState.getCurrentContent();
16 | var currentSelection = selection || editorState.getSelection();
17 | var startKey = currentSelection.getStartKey();
18 | var endKey = currentSelection.getEndKey();
19 | var startOffset = currentSelection.getStartOffset();
20 | var endOffset = currentSelection.getEndOffset();
21 |
22 | var isSameBlock = startKey === endKey;
23 | var selectedBlocks = (0, _getSelectedBlocks2.default)(contentState, startKey, endKey);
24 | var entityFound = false;
25 |
26 | var finalStartOffset = startOffset + 1;
27 | var finalEndOffset = endOffset - 1;
28 |
29 | selectedBlocks.forEach(function (block) {
30 | strategy(block, function (start, end) {
31 | if (entityFound) {
32 | return;
33 | }
34 |
35 | var blockKey = block.getKey();
36 |
37 | if (isSameBlock && (end < finalStartOffset || start > finalEndOffset)) {
38 | return;
39 | } else if (blockKey === startKey && end < finalStartOffset) {
40 | return;
41 | } else if (blockKey === endKey && start > finalEndOffset) {
42 | return;
43 | }
44 |
45 | entityFound = true;
46 | });
47 | });
48 |
49 | return entityFound;
50 | };
51 | };
--------------------------------------------------------------------------------
/publish/editor/utils/stateUtils/styleToCSS.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _CSSProperty = require('react-dom/lib/CSSProperty');
8 |
9 | var VENDOR_PREFIX = /^(moz|ms|o|webkit)-/;
10 | var NUMERIC_STRING = /^\d+$/;
11 | var UPPERCASE_PATTERN = /([A-Z])/g;
12 |
13 | function processStyleName(name) {
14 | return name.replace(UPPERCASE_PATTERN, '-$1').toLowerCase().replace(VENDOR_PREFIX, '-$1-');
15 | }
16 |
17 | function processStyleValue(name, value) {
18 | var isNumeric = void 0;
19 | if (typeof value === 'string') {
20 | isNumeric = NUMERIC_STRING.test(value);
21 | } else {
22 | isNumeric = true;
23 | value = String(value);
24 | }
25 | if (!isNumeric || value === '0' || _CSSProperty.isUnitlessNumber[name] === true) {
26 | return value;
27 | } else {
28 | return value + 'px';
29 | }
30 | }
31 |
32 | function styleToCSS(styleDescr) {
33 | return Object.keys(styleDescr).map(function (name) {
34 | var styleValue = processStyleValue(name, styleDescr[name]);
35 | var styleName = processStyleName(name);
36 | return styleName + ': ' + styleValue;
37 | }).join('; ');
38 | }
39 |
40 | exports.default = styleToCSS;
--------------------------------------------------------------------------------
/publish/global/components/businessComponents.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | UploadImage: require('./businessComponents/UploadImage'),
5 | GroupUpload: require('./businessComponents/GroupUpload')
6 | };
--------------------------------------------------------------------------------
/publish/global/supports/datas/base.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = {
4 | Config: {
5 | version: "2.1.3 (Beta)",
6 | server: {
7 | ajax: 'http://114.55.148.57:8083/' },
8 | watermarkImage: [{
9 | type: "white_small",
10 | tip: "白色小图",
11 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/white_small.png",
12 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS93aGl0ZV9zbWFsbC5wbmc="
13 | }, {
14 | type: "white_big",
15 | tip: "白色大图",
16 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/white_big.png",
17 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS93aGl0ZV9iaWcucG5n"
18 | }, {
19 | type: "gray_small",
20 | tip: "灰色小图",
21 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/gray_small.png",
22 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS9ncmF5X3NtYWxsLnBuZw=="
23 | }, {
24 | type: "gray_big",
25 | tip: "灰色大图",
26 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/gray_big.png",
27 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS9ncmF5X2JpZy5wbmc="
28 | }, {
29 | type: "black_small",
30 | tip: "黑色小图",
31 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/black_small.png",
32 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS9ibGFja19zbWFsbC5wbmc="
33 | }, {
34 | type: "black_big",
35 | tip: "黑色大图",
36 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/black_big.png",
37 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS9ibGFja19iaWcucG5n"
38 | }]
39 | }
40 | };
--------------------------------------------------------------------------------
/publish/global/supports/methods/public.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _Request = require('./Request');
4 |
5 | var _url = require('../datas/url');
6 |
7 | module.exports = {
8 | supportMime: {
9 | image: ["image/jpeg", "image/png", "image/jpg", "image/gif", "image/webp"],
10 | video: ["video/mp4"],
11 | audio: ["audio/mp4", "audio/mp3", "audio/mpeg"]
12 | },
13 | makeGuid: function makeGuid() {
14 | var guid = "";
15 | for (var i = 1; i <= 32; i++) {
16 | var n = Math.floor(Math.random() * 16.0).toString(16);
17 | guid += n;
18 | if (i == 8 || i == 12 || i == 16 || i == 20) guid += "-";
19 | }
20 | return guid;
21 | },
22 |
23 | nowTime: function nowTime() {
24 | var time = Date.parse(new Date()) / 1000;
25 | return time;
26 | },
27 |
28 | checkQiniu: {
29 |
30 | checkQiniuImgToken: function checkQiniuImgToken(key) {
31 |
32 | var timestamp = Date.parse(new Date()) / 1000;
33 | var last_qiniu_token_time = localStorage.getItem("last_qiniu_token_time_" + key);
34 | var mark = false;
35 |
36 | if (last_qiniu_token_time) {
37 | if (timestamp - last_qiniu_token_time < 3500) {
38 | mark = true;
39 | }
40 | }
41 | var qiniu_token = "";
42 | if (localStorage.getItem("qiniu_" + key + "_token") && mark) {
43 | qiniu_token = localStorage.getItem("qiniu_" + key + "_token");
44 | }
45 | return qiniu_token;
46 | },
47 | returnToken: function returnToken() {
48 | var uploadConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
49 | var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'image';
50 | var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
51 |
52 | if (Object.keys(uploadConfig).length == 0) {
53 | return false;
54 | }
55 | var token = this.checkQiniuImgToken(key);
56 | token = !!token == true ? token : this.getQiniuToken(uploadConfig, key, params);
57 | return token;
58 | },
59 | getQiniuToken: function getQiniuToken(uploadConfig) {
60 | var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'image';
61 | var params = arguments[2];
62 |
63 | var token = "";
64 | var url = void 0;
65 | if (type == 'image') {
66 | url = uploadConfig.QINIU_IMG_TOKEN_URL;
67 | } else if (type == 'video') {
68 | url = uploadConfig.QINIU_VIDEO_TOKEN_URL;
69 | } else if (type == 'file') {
70 | url = uploadConfig.QINIU_FILE_TOKEN_URL;
71 | } else if (type == 'manage') {
72 | url = uploadConfig.QINIU_MANAGE_TOKEN_URL;
73 | } else {
74 | url = uploadConfig.QINIU_IMG_TOKEN_URL;
75 | }
76 |
77 | _Request.ajax.requestData({
78 | url: url,
79 | method: 'post',
80 | isAsync: true,
81 | defaultData: {}
82 | }, params, function (data) {
83 | token = data.uptoken;
84 |
85 | localStorage.setItem("qiniu_" + type + "_token", token);
86 | localStorage.setItem("last_qiniu_token_time_" + type, Date.parse(new Date()) / 1000);
87 | }, function () {
88 | return false;
89 | });
90 | return token;
91 | }
92 | }
93 | };
--------------------------------------------------------------------------------
/publish/global/supports/publicDatas.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | PRO_BASE: require('./datas/base'),
5 | PRO_URL: require('./datas/url'),
6 | PRO_REQUEST: require('./methods/Request'),
7 | PRO_COMMON: require('./methods/common'),
8 | PRO_QINIU: require('./methods/public')
9 | };
--------------------------------------------------------------------------------
/publish/global/supports/resources/blur.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/publish/global/supports/resources/custom.css:
--------------------------------------------------------------------------------
1 | .openFullAll {
2 | position: fixed;
3 | top: 0;
4 | right: 0;
5 | bottom: 0;
6 | left: 0;
7 | z-index: 999;
8 | overflow: auto;
9 | }
10 |
11 | .watermark_grid {
12 | display: block;
13 | position: absolute;
14 | top: 0;
15 | background-repeat: no-repeat;
16 | }
17 |
18 | .watermark_grid span {
19 | display: inline-block;
20 | border: 1px dashed rgba(255, 255, 255, .2);
21 | cursor: pointer;
22 | }
23 |
24 | .editor-inline-image tips {
25 | font-size: 12px;
26 | position: absolute;
27 | right: 0;
28 | color: #aaa;
29 | }
30 |
31 | .breakImages>div {
32 | width: 100px;
33 | height: 100px;
34 | overflow: hidden;
35 | display: inline-block;
36 | margin: 10px 10px 0 0;
37 | background-clip: content-box;
38 | background-size: cover;
39 | background-repeat: no-repeat;
40 | background-position: center;
41 | border: 1px solid #E9E9E9;
42 | border-radius: 3px;
43 | overflow: hidden;
44 | }
45 |
--------------------------------------------------------------------------------
/publish/global/supports/resources/default/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/publish/global/supports/resources/default/iconfont.eot
--------------------------------------------------------------------------------
/publish/global/supports/resources/default/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/publish/global/supports/resources/default/iconfont.ttf
--------------------------------------------------------------------------------
/publish/global/supports/resources/default/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/publish/global/supports/resources/default/iconfont.woff
--------------------------------------------------------------------------------
/publish/global/supports/resources/iconfont.css:
--------------------------------------------------------------------------------
1 |
2 | @font-face {font-family: "iconfont";
3 | src: url('iconfont.eot?t=1479085947184'); /* IE9*/
4 | src: url('iconfont.eot?t=1479085947184#iefix') format('embedded-opentype'), /* IE6-IE8 */
5 | url('iconfont.woff?t=1479085947184') format('woff'), /* chrome, firefox */
6 | url('iconfont.ttf?t=1479085947184') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
7 | url('iconfont.svg?t=1479085947184#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .iconfont {
11 | font-family:"iconfont" !important;
12 | font-size:16px;
13 | font-style:normal;
14 | -webkit-font-smoothing: antialiased;
15 | -webkit-text-stroke-width: 0.2px;
16 | -moz-osx-font-smoothing: grayscale;
17 | }
18 |
19 | .icon-panorama_time:before { content: "\ea16"; }
20 |
21 | .icon-shangdian:before { content: "\ea01"; }
22 |
23 | .icon-yonghuzumingcheng:before { content: "\ea36"; }
24 |
25 | .icon-panorama_joinuser:before { content: "\ea18"; }
26 |
27 | .icon-panorama_joindevice:before { content: "\ea19"; }
28 |
29 | .icon-shangpin:before { content: "\e998"; }
30 |
31 | .icon-newsVerify:before { content: "\ea26"; }
32 |
33 | .icon-access_user:before { content: "\ea1d"; }
34 |
35 | .icon-xitong:before { content: "\ea1c"; }
36 |
37 | .icon-dropdown:before { content: "\ea0b"; }
38 |
39 | .icon-yidianhaoleibie:before { content: "\ea2e"; }
40 |
41 | .icon-unie60e:before { content: "\ea23"; }
42 |
43 | .icon-yidianhaowenzhang:before { content: "\ea30"; }
44 |
45 | .icon-empty:before { content: "\ea0d"; }
46 |
47 | .icon-lunbozutu:before { content: "\ea06"; }
48 |
49 | .icon-quanzi:before { content: "\e991"; }
50 |
51 | .icon-recycleNews:before { content: "\ea24"; }
52 |
53 | .icon-tiezi:before { content: "\e995"; }
54 |
55 | .icon-unie6672:before { content: "\e996"; }
56 |
57 | .icon-untitled22:before { content: "\e993"; }
58 |
59 | .icon-unie604:before { content: "\e932"; }
60 |
61 | .icon-untitled144:before { content: "\ea04"; }
62 |
63 | .icon-newsChannel1:before { content: "\ea27"; }
64 |
65 | .icon-quanziline:before { content: "\e992"; }
66 |
67 | .icon-piliangicon:before { content: "\ea08"; }
68 |
69 | .icon-yidianhaotiaomu:before { content: "\ea2f"; }
70 |
71 | .icon-huodong:before { content: "\e999"; }
72 |
73 | .icon-paixu:before { content: "\ea03"; }
74 |
75 | .icon-news:before { content: "\ea2a"; }
76 |
77 | .icon-jiangpai:before { content: "\ea1b"; }
78 |
79 | .icon-appclient:before { content: "\ea40"; }
80 |
81 | .icon-neirong:before { content: "\e994"; }
82 |
83 | .icon-paixu1:before { content: "\ea0e"; }
84 |
85 | .icon-newsComment:before { content: "\ea29"; }
86 |
87 | .icon-bumen:before { content: "\ea34"; }
88 |
89 | .icon-pinpai:before { content: "\ea02"; }
90 |
91 | .icon-newsChannel:before { content: "\ea28"; }
92 |
93 | .icon-yonghuxinxixian:before { content: "\ea07"; }
94 |
95 | .icon-panorama_app:before { content: "\ea1a"; }
96 |
97 | .icon-panorama_today:before { content: "\ea12"; }
98 |
99 | .icon-yaochi:before { content: "\ea09"; }
100 |
101 | .icon-gengxinupdated:before { content: "\ea21"; }
102 |
103 | .icon-panorama_version:before { content: "\ea14"; }
104 |
105 | .icon-wochuangjiande:before { content: "\ea38"; }
106 |
107 | .icon-ditu-copy-copy:before { content: "\e997"; }
108 |
109 | .icon-jingxuan-copy:before { content: "\ea05"; }
110 |
111 | .icon-yichu:before { content: "\ea0a"; }
112 |
113 | .icon-panorama_newboot:before { content: "\ea13"; }
114 |
115 | .icon-panorama:before { content: "\ea15"; }
116 |
117 | .icon-panorama_device:before { content: "\ea17"; }
118 |
119 | .icon-lunbotuzujian:before { content: "\ea39"; }
120 |
121 | .icon-order:before { content: "\ea0c"; }
122 |
123 | .icon-sort:before { content: "\ea10"; }
124 |
125 | .icon-zhanghuyuquanxian:before { content: "\ea32"; }
126 |
127 | .icon-panorama_action:before { content: "\ea11"; }
128 |
129 | .icon-yidianhaoshenhe:before { content: "\ea31"; }
130 |
131 | .icon-jiaosequanxian0101:before { content: "\ea1f"; }
132 |
133 | .icon-city:before { content: "\ea25"; }
134 |
135 | .icon-startpage:before { content: "\ea41"; }
136 |
137 | .icon-jiaosesheding:before { content: "\ea1e"; }
138 |
139 | .icon-chuangjianjiaose:before { content: "\ea22"; }
140 |
141 | .icon-yidianhao:before { content: "\ea2d"; }
142 |
143 | .icon-gongzuoxiang:before { content: "\ea20"; }
144 |
145 | .icon-grab:before { content: "\ea2c"; }
146 |
147 | .icon-draft:before { content: "\ea2b"; }
148 |
149 | .icon-channelpd-copy:before { content: "\ea33"; }
150 |
151 | .icon-bumen-copy:before { content: "\ea37"; }
152 |
153 | .icon-10106-copy:before { content: "\ea35"; }
154 |
155 | .icon-news_radar:before { content: "\ea49"; }
156 |
157 | .icon-news_radar_list:before { content: "\ea50"; }
158 |
159 | .icon-news_radar_comment:before { content: "\ea51"; }
160 |
--------------------------------------------------------------------------------
/publish/global/supports/resources/system.less:
--------------------------------------------------------------------------------
1 | @import "custom.css";
2 | @import "fonticon/default.less";
--------------------------------------------------------------------------------
/publish/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = require('./editor/index');
4 | exports.LzEditor = require('./editor/index');
--------------------------------------------------------------------------------
/publish/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _test = require('./test.jsx');
4 |
5 | var _test2 = _interopRequireDefault(_test);
6 |
7 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
--------------------------------------------------------------------------------
/publish/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-lz-editor",
3 | "version": "0.12.1",
4 | "description": "An open source react rich-text editor (mordern react editor includes media support such as texts, images, videos, audios, links etc.), development based on Draft-Js and Ant-design, good support html, markdown, draft-raw mode.",
5 | "main": "index",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+ssh://git@github.com/leejaen/react-lz-editor.git"
12 | },
13 | "keywords": [
14 | "react editor",
15 | "draft-js",
16 | "react-rich-editor",
17 | "react-lz-editor"
18 | ],
19 | "devDependencies": {
20 | "babel-cli": "^6.6.5",
21 | "babel-loader": "^6.2.4",
22 | "babel-plugin-transform-class-properties": "^6.19.0",
23 | "babel-preset-es2015": "^6.6.0",
24 | "babel-preset-react": "^6.16.0",
25 | "babel-preset-stage-2": "^6.18.0",
26 | "css-loader": "^0.23.1",
27 | "eslint": "^3.12.2",
28 | "eslint-plugin-react": "^6.8.0",
29 | "file-loader": "^0.8.5",
30 | "flow-bin": "^0.37.4",
31 | "less": "^2.7.1",
32 | "less-loader": "^2.2.3",
33 | "react": "^0.14.8",
34 | "style-loader": "^0.13.1",
35 | "url-loader": "^0.5.7",
36 | "webpack": "^1.12.14",
37 | "webpack-dev-server": "^1.14.1"
38 | },
39 | "dependencies": {
40 | "antd": "^2.8.3",
41 | "draft-js": "^0.10.0",
42 | "immutable": "^3.8.1",
43 | "js-base64": "^2.1.9",
44 | "lodash": "^4.17.3",
45 | "synthetic-dom": "^0.2.1"
46 | },
47 | "author": "leejaen@gmail.com",
48 | "license": "ISC",
49 | "bugs": {
50 | "url": "https://github.com/leejaen/react-lz-editor/issues"
51 | },
52 | "homepage": "https://github.com/leejaen/react-lz-editor#readme"
53 | }
54 |
--------------------------------------------------------------------------------
/src/editor/components.css:
--------------------------------------------------------------------------------
1 | .editorHidden {
2 | z-index: 10;
3 | overflow: hidden;
4 | position: relative;
5 | }
6 |
7 | .editor_container {
8 | border: 1px solid #E9E9E9;
9 | background-color: #F9F9F9;
10 | padding: 5px;
11 | }
12 |
13 | .editor_top {
14 | height: 30px;
15 | width: 100%;
16 | }
17 |
18 | .editor_middle {
19 | background-color: #FFF;
20 | border: 1px solid #E9E9E9;
21 | box-shadow: 3px 3px 5px #AAA inset;
22 | }
23 |
24 | .editor_bottom {
25 | height: 30px;
26 | width: 100%;
27 | }
28 |
29 | .superFancyBlockquote {
30 | color: #999;
31 | font-style: italic;
32 | text-align: center;
33 | }
34 | /*.public-DraftEditor-content>div>div>div>div:before{content:"¶"}*/
35 | .editor-inline-image img,
36 | .editor-inline-video video,
37 | .editor-inline-audio audio {
38 | padding: 0 5px;
39 | display: block;
40 | margin: 0 auto;
41 | max-width: 100%;
42 | }
43 |
44 | .RichEditor-root {
45 | background: #FFF;
46 | font-size: 14px;
47 | padding: 15px;
48 | }
49 |
50 | .RichEditor-editor {
51 | cursor: text;
52 | font-size: 16px;
53 | }
54 |
55 | .RichEditor-toolbar {
56 | border-bottom: 1px solid #DDD;
57 | }
58 |
59 | .public-DraftStyleDefault-ul {
60 | list-style: disc;
61 | padding-left: 2.0rem
62 | }
63 |
64 | .public-DraftStyleDefault-ol {
65 | padding-left: 2.0rem;
66 | list-style-type: decimal;
67 | }
68 |
69 | .RichEditor-editor .public-DraftEditorPlaceholder-root,
70 | .RichEditor-editor .public-DraftEditor-content {
71 | margin: 0 -15px -15px;
72 | padding: 15px;
73 | }
74 |
75 | .RichEditor-editor .public-DraftEditor-content {
76 | min-height: 100px;
77 | line-height: initial;
78 | }
79 |
80 | .RichEditor-editor .public-DraftEditor-content>div>* {
81 | margin: 10px 0;
82 | }
83 |
84 | .RichEditor-editor .public-DraftEditor-content pre {
85 | white-space: pre-wrap;
86 | word-wrap: break-word;
87 | }
88 |
89 | .RichEditor-hidePlaceholder .public-DraftEditorPlaceholder-root {
90 | display: none;
91 | }
92 |
93 | .RichEditor-editor .RichEditor-blockquote {
94 | border-left: 5px solid #EEE;
95 | color: #666;
96 | font-family: 'Hoefler Text', 'Georgia', serif;
97 | font-style: italic;
98 | margin: 16px 0;
99 | padding: 10px 20px;
100 | }
101 |
102 | .RichEditor-editor .RichEditor-alignment-left {
103 | text-align: left;
104 | }
105 |
106 | .RichEditor-editor .RichEditor-alignment-center {
107 | text-align: center;
108 | }
109 |
110 | .RichEditor-editor .RichEditor-alignment-right {
111 | text-align: right;
112 | }
113 |
114 | .RichEditor-editor .RichEditor-alignment-justify {
115 | text-align: justify;
116 | }
117 |
118 | .RichEditor-editor .public-DraftStyleDefault-pre {
119 | background-color: rgba(0, 0, 0, 0.05);
120 | font-family: 'Inconsolata', 'Menlo', 'Consolas', monospace;
121 | font-size: 16px;
122 | padding: 20px;
123 | }
124 |
125 | .RichEditor-controls {
126 | font-family: 'Helvetica', sans-serif;
127 | font-size: 14px;
128 | margin-bottom: 5px;
129 | user-select: none;
130 | display: inline;
131 | border-left: 1px solid #EEE;
132 | }
133 | .RichEditor-controls .ant-btn{
134 | transition:none!important;
135 | -o-transition:none!important;
136 | -ms-transition:none!important;
137 | -moz-transition:none!important;
138 | -webkit-transition:none!important;
139 | }
140 | .RichEditor-controls-split {
141 | padding-right: 20px
142 | }
143 |
144 | .RichEditor-color span {
145 | margin: 0;
146 | width: 16px;
147 | line-height: 28px;
148 | }
149 |
150 | .RichEditor-styleButton {
151 | color: #999;
152 | cursor: pointer;
153 | margin: 0 8px;
154 | padding: 3px 5px !important;
155 | display: inline-block;
156 | position: relative;
157 | margin: 8px 5px;
158 | line-height: 20px;
159 | font-size: 16px;
160 | border: 1px solid transparent;
161 | }
162 | .RichEditor-styleButton.ant-btn.ant-btn-primary.ant-btn-icon-only{
163 | color: #fff;
164 | }
165 |
166 | .RichEditor-styleButton i.anticon {
167 | margin-left: 0px !important;
168 | }
169 |
170 | .RichEditor-activeButton {
171 | color: #fff;
172 | border-radius: 5px;
173 | /*Can not use the default color, otherwise it will replace the custom theme color*/
174 | }
175 |
176 | .RichEditor-color {
177 | display: inline-block;
178 | height: 16px;
179 | width: 16px;
180 | overflow: hidden;
181 | top: 3px;
182 | position: relative;
183 | border-radius: 3px;
184 | margin: 0px 5px;
185 | }
186 |
187 | .RichEditor-color-active {}
188 |
189 | .RichEditor-color:nth-child(2n+1) {}
190 | #text-editor-affix>.ant-affix{background-color:#fff!important;}
191 | .disabled-mask {
192 | background: rgba(200,200,200,0.5);
193 | width: 100%;
194 | height: 100%;
195 | top: 0;
196 | display: block;
197 | position: absolute;
198 | pointer-events: unset;
199 | cursor: not-allowed;
200 | left: 0;
201 | }
202 | .disabled-editor{
203 | filter: grayscale(100%);
204 | }
205 |
--------------------------------------------------------------------------------
/src/editor/config/colorStyleMap.jsx:
--------------------------------------------------------------------------------
1 |
2 | // This object provides the styling information for our custom color styles.
3 | const colorStyleMap = {
4 | grapeFruit1: {
5 | color: '#ED5565'
6 | },
7 | grapeFruit2: {
8 | color: '#Da4453'
9 | },
10 | bitterSweet1: {
11 | color: '#fc6e51'
12 | },
13 | bitterSweet2: {
14 | color: '#e9573f'
15 | },
16 | sunFlower1: {
17 | color: '#ffce54'
18 | },
19 | sunFlower2: {
20 | color: '#f6bb42'
21 | },
22 | grass1: {
23 | color: '#a0d468'
24 | },
25 | grass2: {
26 | color: '#bcc152'
27 | },
28 | mint1: {
29 | color: '#48cfad'
30 | },
31 | mint2: {
32 | color: '#37bc9b'
33 | },
34 | aqua1: {
35 | color: '#4fc1e9'
36 | },
37 | aqua2: {
38 | color: '#38afda'
39 | },
40 | blueJeans1: {
41 | color: '#5d9cec'
42 | },
43 | blueJeans2: {
44 | color: '#4a89dc'
45 | },
46 | lavander1: {
47 | color: '#ac92ec'
48 | },
49 | lavander2: {
50 | color: '#967adc'
51 | },
52 | mediumGray1: {
53 | color: '#ccd1d9'
54 | },
55 | mediumGray2: {
56 | color: '#aab2bd'
57 | },
58 | darkGray1: {
59 | color: '#656d78'
60 | },
61 | darkGray2: {
62 | color: '#434a54'
63 | }
64 | };
65 |
66 | module.exports=colorStyleMap;
67 |
--------------------------------------------------------------------------------
/src/editor/decorators/AudioDecorator.jsx:
--------------------------------------------------------------------------------
1 | /* @flow */
2 | import AudioSpan from './AudioSpan';
3 | import {Entity} from 'draft-js';
4 | import {ENTITY_TYPE} from '../utils/stateUtils/main';
5 |
6 | import type {ContentBlock} from 'draft-js';
7 | // import {ContentBlock} from 'draft-js';
8 | type EntityRangeCallback = (start: number, end: number) => void;
9 | function findAudioEntities(contentBlock: ContentBlock, callback: EntityRangeCallback) {
10 | // function findAudioEntities(contentBlock: ContentBlock, callback) {
11 |
12 | contentBlock.findEntityRanges((character) => {
13 | const entityKey = character.getEntity();
14 | return (
15 | entityKey != null &&
16 | Entity.get(entityKey).getType() === ENTITY_TYPE.AUDIO
17 | );
18 | }, callback);
19 | }
20 |
21 | export default {
22 | strategy: findAudioEntities,
23 | component: AudioSpan,
24 | };
25 |
--------------------------------------------------------------------------------
/src/editor/decorators/AudioSpan.jsx:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | // import autobind from 'class-autobind';
4 | import React, {Component} from 'react';
5 | import {Entity} from 'draft-js';
6 |
7 | // $FlowIssue - Flow doesn't understand CSS Modules
8 | import styles from './decoratorStyle.css';
9 |
10 | export default class AudioSpan extends Component {
11 | constructor(props : Props) {
12 | super(props);
13 | // autobind(this);
14 | const entity = Entity.get(this.props.entityKey);
15 | const {width, height} = entity.getData();
16 | this.state = {
17 | width,
18 | height
19 | };
20 | }
21 |
22 | componentDidMount() {
23 | const {width
24 | , height} = this.state;
25 | const entity = Entity.get(this.props.entityKey);
26 | const audio = document.createElement('audio');
27 | const {src} = entity.getData();
28 | audio.src = src;
29 | audio.onload = () => {
30 | if (width == null || height == null) {
31 | // TODO: isMounted?
32 | this.setState({width: audio.width, height: audio.height});
33 | Entity.mergeData(this.props.entityKey, {
34 | width: audio.width,
35 | height: audio.height,
36 | originalWidth: audio.width,
37 | originalHeight: audio.height
38 | });
39 | }
40 | };
41 | }
42 |
43 | render() {
44 | const {width, height} = this.state;
45 | //let {className} = this.props;
46 | const entity = Entity.get(this.props.entityKey);
47 | const {src} = entity.getData();
48 | //console.log("styles.root: ", styles.root); className = cx(className, styles.root);
49 | const audioStyle = {
50 | verticalAlign: 'bottom',
51 | backgroundImage: `url("${src}")`,
52 | backgroundSize: `${width}px ${height}px`,
53 | lineHeight: `${height}px`,
54 | fontSize: `${height}px`,
55 | width,
56 | height,
57 | letterSpacing: width
58 | };
59 |
60 | // return ( {this.props.children} );
62 | return (
63 |
64 |
65 |
66 | );
67 | }
68 |
69 | _onClick() {
70 | //console.log('audio click');
71 | }
72 |
73 | _handleResize(event : Object, data : Object) {
74 | const {width, height} = data.size;
75 | this.setState({width, height});
76 | Entity.mergeData(this.props.entityKey, {width, height});
77 | }
78 | }
79 | //AudioSpan.propTypes={ children: React.PropTypes, entityKey: string, className?: string }
80 |
81 | AudioSpan.defaultProps = {
82 | children: null,
83 | entityKey: "",
84 | className: ""
85 | }
86 |
--------------------------------------------------------------------------------
/src/editor/decorators/ImageDecorator.jsx:
--------------------------------------------------------------------------------
1 | /* @flow */
2 | import ImageSpan from './ImageSpan';
3 | import {Entity} from 'draft-js';
4 | import {ENTITY_TYPE} from '../utils/stateUtils/main';
5 |
6 | import type {ContentBlock} from 'draft-js';
7 |
8 | type EntityRangeCallback = (start: number, end: number) => void;
9 |
10 | function findImageEntities(contentBlock: ContentBlock, callback: EntityRangeCallback) {
11 | contentBlock.findEntityRanges((character) => {
12 | const entityKey = character.getEntity();
13 | return (
14 | entityKey != null &&
15 | Entity.get(entityKey).getType() === ENTITY_TYPE.IMAGE
16 | );
17 | }, callback);
18 | }
19 |
20 | export default {
21 | strategy: findImageEntities,
22 | component: ImageSpan,
23 | };
24 |
--------------------------------------------------------------------------------
/src/editor/decorators/ImageSpan.jsx:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | // import autobind from 'class-autobind';
4 | import React, {Component} from 'react';
5 | import ReactDom from 'react-dom';
6 | import {Entity,EditorState} from 'draft-js';
7 | import {message} from 'antd';
8 |
9 | // $FlowIssue - Flow doesn't understand CSS Modules
10 | import styles from './decoratorStyle.css';
11 |
12 | export default class ImageSpan extends Component {
13 | constructor(props : Props) {
14 | super(props);
15 | // autobind(this);
16 | const entity = Entity.get(this.props.entityKey);
17 | const {width, height} = entity.getData();
18 | this.state = {
19 | width,
20 | height,
21 | imageSrc:''
22 | };
23 | this.onImageClick=this._onImageClick.bind(this);
24 | this.onDoubleClick=this._onDoubleClick.bind(this);
25 | }
26 |
27 | componentDidMount() {
28 | const {width, height} = this.state;
29 | const entity = Entity.get(this.props.entityKey);
30 | const image = new Image();
31 | let {src} = entity.getData();
32 | src=src.replace(/[?#&].*$/g,"");
33 | this.setState({imageSrc:src});
34 | image.src = this.state.imageSrc;
35 | image.onload = () => {
36 | if (width == null || height == null) {
37 | // TODO: isMounted?
38 | this.setState({width: image.width, height: image.height});
39 | Entity.mergeData(this.props.entityKey, {
40 | width: image.width,
41 | height: image.height,
42 | originalWidth: image.width,
43 | originalHeight: image.height
44 | });
45 | }
46 | };
47 | }
48 |
49 | render() {
50 | const {width, height} = this.state;
51 | //let {className} = this.props;
52 | let key=this.props.entityKey;
53 | const entity = Entity.get(key);
54 | const {src} = entity.getData();
55 | // this.setState({imageSrc:src});
56 | //console.log("styles.root: ", styles.root); className = cx(className, styles.root);
57 | const imageStyle = {
58 | verticalAlign: 'bottom',
59 | backgroundImage: `url("${this.state.imageSrc}")`,
60 | backgroundSize: `${width}px ${height}px`,
61 | lineHeight: `${height}px`,
62 | fontSize: `${height}px`,
63 | width,
64 | height,
65 | letterSpacing: width
66 | };
67 |
68 | // return ( {this.props.children} );
70 | // {imageStyle.width&&imageStyle.height?`Width ${imageStyle.width}px Height ${imageStyle.height}px`:""}
71 | return (
72 |
73 |
{this.onImageClick(event,key);event.stopPropagation();}} onDoubleClick={this.onDoubleClick}/>
74 |
75 | );
76 | }
77 |
78 | _onDoubleClick() {
79 | //Popup a modal to edit
80 | let currentPicture=ReactDom.findDOMNode(this).querySelector("img");
81 | let pictureWidth=currentPicture.naturalWidth;
82 | let pictureSrc=currentPicture.src;
83 | // console.log("pictureSrc",pictureSrc);
84 | // currentPicture.src="http://www.cbinews.com/article/image/20161027/20161027091805_674.png"
85 | }
86 | _onImageClick(e:any,key){
87 | let currentPicture=ReactDom.findDOMNode(this).querySelector("img");
88 | // console.log("currentPicture:",currentPicture.src);
89 | let pictureWidth=currentPicture.naturalWidth;
90 | // console.log("this",this);
91 | // console.log("this.props.children[0].key",this.props.children[0].key);
92 | // console.log("this.state.editorState",EditorState);
93 | // console.log("key",key);
94 | // console.log("pictureWidth:",pictureWidth);
95 |
96 | const editorState=EditorState.createEmpty();
97 | const selection = editorState.getSelection();
98 | // console.log("selection",selection);
99 | const blockTree = editorState.getBlockTree(this.props.children[0].key);
100 | // console.log("blockTree",blockTree);
101 | // this.setState({imageSrc:"https://image.qiluyidian.mobi/87928142151028397142qn1d609U291dGhFYXN0.jpg"});
102 | if (pictureWidth==0) {
103 | message.error("图片地址错误!");
104 | }else if(pictureWidth>650) {
105 | message.error("图片尺寸过大将会导致用户流量浪费!请调整至最大650px。",10);
106 | }
107 | }
108 |
109 | _handleResize(event : Object, data : Object) {
110 | const {width, height} = data.size;
111 | this.setState({width, height});
112 | Entity.mergeData(this.props.entityKey, {width, height});
113 | }
114 | }
115 | //ImageSpan.propTypes={ children: React.PropTypes, entityKey: string, className?: string }
116 |
117 | ImageSpan.defaultProps = {
118 | children: null,
119 | entityKey: "",
120 | className: ""
121 | }
122 |
--------------------------------------------------------------------------------
/src/editor/decorators/LinkDecorator.jsx:
--------------------------------------------------------------------------------
1 | /* @flow */
2 | import React from 'react';
3 | import {Entity} from 'draft-js';
4 | import {ENTITY_TYPE} from '../utils/stateUtils/main';
5 |
6 | import type {ContentBlock} from 'draft-js';
7 |
8 | // TODO: Use a more specific type here.
9 | type ReactNode = any;
10 |
11 | type Props = {
12 | children: ReactNode,
13 | entityKey: string,
14 | };
15 |
16 | type EntityRangeCallback = (start: number, end: number) => void;
17 |
18 | function Link(props_: Props): React.Element {
19 | const {url} = Entity.get(props_.entityKey).getData();
20 | return (
21 | {props_.children}
22 | );
23 |
24 |
25 |
26 | // const {url} = Entity.get(props.entityKey).getData();
27 | // let currentStyle = props.editorState
28 | // ? props.editorState.getCurrentInlineStyle()
29 | // : {};
30 | // return (
31 | //
34 | // {props.children}
35 | //
36 | // );
37 | }
38 |
39 | function findLinkEntities(contentBlock: ContentBlock, callback: EntityRangeCallback) {
40 | contentBlock.findEntityRanges((character) => {
41 | const entityKey = character.getEntity();
42 | return (
43 | entityKey != null &&
44 | Entity.get(entityKey).getType() === ENTITY_TYPE.LINK
45 | );
46 | }, callback);
47 | }
48 |
49 | export default {
50 | strategy: findLinkEntities,
51 | component: Link,
52 | };
53 |
--------------------------------------------------------------------------------
/src/editor/decorators/VideoDecorator.jsx:
--------------------------------------------------------------------------------
1 | /* @flow */
2 | import VideoSpan from './VideoSpan';
3 | import {Entity} from 'draft-js';
4 | import {ENTITY_TYPE} from '../utils/stateUtils/main';
5 |
6 | import type {ContentBlock} from 'draft-js';
7 |
8 | type EntityRangeCallback = (start: number, end: number) => void;
9 |
10 | function findVideoEntities(contentBlock: ContentBlock, callback: EntityRangeCallback) {
11 | contentBlock.findEntityRanges((character) => {
12 | const entityKey = character.getEntity();
13 | return (
14 | entityKey != null &&
15 | Entity.get(entityKey).getType() === ENTITY_TYPE.VIDEO
16 | );
17 | }, callback);
18 | }
19 |
20 | export default {
21 | strategy: findVideoEntities,
22 | component: VideoSpan,
23 | };
24 |
--------------------------------------------------------------------------------
/src/editor/decorators/VideoSpan.jsx:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | // import autobind from 'class-autobind';
4 | import React, {Component} from 'react';
5 | import {Entity} from 'draft-js';
6 |
7 | // $FlowIssue - Flow doesn't understand CSS Modules
8 | import styles from './decoratorStyle.css';
9 |
10 | export default class VideoSpan extends Component {
11 | constructor(props : Props) {
12 | super(props);
13 | // autobind(this);
14 | const entity = Entity.get(this.props.entityKey);
15 | const {width, height} = entity.getData();
16 | this.state = {
17 | width,
18 | height
19 | };
20 | }
21 |
22 | componentDidMount() {
23 | const {width
24 | , height} = this.state;
25 | const entity = Entity.get(this.props.entityKey);
26 | const video = document.createElement('video');
27 | const {src} = entity.getData();
28 | video.src = src;
29 | video.onload = () => {
30 | if (width == null || height == null) {
31 | // TODO: isMounted?
32 | this.setState({width: video.width, height: video.height});
33 | Entity.mergeData(this.props.entityKey, {
34 | width: video.width,
35 | height: video.height,
36 | originalWidth: video.width,
37 | originalHeight: video.height
38 | });
39 | }
40 | };
41 | }
42 |
43 | render() {
44 | const {width, height} = this.state;
45 | //let {className} = this.props;
46 | const entity = Entity.get(this.props.entityKey);
47 | const {src} = entity.getData();
48 | //console.log("styles.root: ", styles.root); className = cx(className, styles.root);
49 | const videoStyle = {
50 | verticalAlign: 'bottom',
51 | backgroundImage: `url("${src}")`,
52 | backgroundSize: `${width}px ${height}px`,
53 | lineHeight: `${height}px`,
54 | fontSize: `${height}px`,
55 | width,
56 | height,
57 | letterSpacing: width
58 | };
59 |
60 | // return ( {this.props.children} );
62 | return (
63 |
64 |
65 |
66 | );
67 | }
68 |
69 | _onClick() {
70 | //console.log('video click');
71 | }
72 |
73 | _handleResize(event : Object, data : Object) {
74 | const {width, height} = data.size;
75 | this.setState({width, height});
76 | Entity.mergeData(this.props.entityKey, {width, height});
77 | }
78 | }
79 | //VideoSpan.propTypes={ children: React.PropTypes, entityKey: string, className?: string }
80 |
81 | VideoSpan.defaultProps = {
82 | children: null,
83 | entityKey: "",
84 | className: ""
85 | }
86 |
--------------------------------------------------------------------------------
/src/editor/decorators/decoratorStyle.css:
--------------------------------------------------------------------------------
1 | .root {
2 | background-repeat: no-repeat;
3 | display: inline-block;
4 | overflow: hidden;
5 | cursor: pointer;
6 | }
7 |
8 | .resize {
9 | border: 1px dashed #78a300;
10 | position: relative;
11 | max-width: 100%;
12 | display: inline-block;
13 | line-height: 0;
14 | top: -1px;
15 | left: -1px
16 | }
17 |
18 | .resizeHandle {
19 | cursor: nwse-resize;
20 | position: absolute;
21 | z-index: 2;
22 | line-height: 1;
23 | bottom: -4px;
24 | right: -5px;
25 | border: 1px solid white;
26 | background-color: #78a300;
27 | width: 8px;
28 | height: 8px;
29 | }
30 | figure{
31 | text-align: center;
32 | overflow: hidden;
33 | }
34 | figure video {
35 | max-width: 300px;
36 | min-width: 300px;
37 | max-height: 200px;
38 | min-height: 200px;
39 | }
40 | figure img,
41 | figure video,
42 | figure audio {
43 | display: block;
44 | margin: 0 auto;
45 | max-width: 100%;
46 | }
47 |
48 | .editor-inline-image,
49 | .editor-inline-video,
50 | .editor-inline-audio
51 | {
52 | display: inline-block;
53 | overflow: hidden;
54 | cursor: pointer;
55 | width: 100%!important;
56 | }
57 | .editor-inline-image:hover,
58 | .editor-inline-video:hover,
59 | .editor-inline-audio:hover{
60 | background-color:#f7f7f7
61 |
62 | }
63 | .editor-inline-image span,
64 | .editor-inline-video span,
65 | .editor-inline-audio span {
66 | font-size: 100px;
67 | /*color: rgba(0, 0, 0, 0);*/
68 | position: absolute;
69 | left: -10px
70 | }
71 |
--------------------------------------------------------------------------------
/src/editor/decorators/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | LinkDecorator :require ("./LinkDecorator"),
3 | ImageDecorator :require ("./ImageDecorator"),
4 | VideoDecorator :require ("./VideoDecorator"),
5 | AudioDecorator :require ("./AudioDecorator")
6 | };
7 |
--------------------------------------------------------------------------------
/src/editor/helpers/combineOrderedStyles.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | type Attributes = {[key: string]: string};
4 | type StyleDescr = {[key: string]: number | string};
5 | type RenderConfig = {
6 | element?: string;
7 | attributes?: Attributes;
8 | style?: StyleDescr;
9 | };
10 | type StyleMap = {[styleName: string]: RenderConfig};
11 | type StyleOrder = Array;
12 | type OrderedStyleMap = [StyleMap, StyleOrder];
13 |
14 | function combineOrderedStyles(
15 | customMap: ?StyleMap,
16 | defaults: OrderedStyleMap,
17 | ): OrderedStyleMap {
18 | if (customMap == null) {
19 | return defaults;
20 | }
21 | let [defaultStyleMap, defaultStyleOrder] = defaults;
22 | let styleMap = {...defaultStyleMap};
23 | let styleOrder = [...defaultStyleOrder];
24 | for (let styleName of Object.keys(customMap)) {
25 | if (defaultStyleMap.hasOwnProperty(styleName)) {
26 | let defaultStyles = defaultStyleMap[styleName];
27 | styleMap[styleName] = {...defaultStyles, ...customMap[styleName]};
28 | } else {
29 | styleMap[styleName] = customMap[styleName];
30 | styleOrder.push(styleName);
31 | }
32 | }
33 | return [styleMap, styleOrder];
34 | }
35 |
36 | export default combineOrderedStyles;
37 |
--------------------------------------------------------------------------------
/src/editor/helpers/normalizeAttributes.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | type Attributes = {[key: string]: string};
4 | type StringMap = {[key: string]: string};
5 |
6 | // Lifted from: https://github.com/facebook/react/blob/master/src/renderers/dom/shared/HTMLDOMPropertyConfig.js
7 | const ATTR_NAME_MAP: StringMap = {
8 | acceptCharset: 'accept-charset',
9 | className: 'class',
10 | htmlFor: 'for',
11 | httpEquiv: 'http-equiv',
12 | };
13 |
14 | function normalizeAttributes(attributes: ?Attributes) {
15 | if (attributes == null) {
16 | return attributes;
17 | }
18 | let normalized = {};
19 | let didNormalize = false;
20 | for (let name of Object.keys(attributes)) {
21 | let newName = name;
22 | if (ATTR_NAME_MAP.hasOwnProperty(name)) {
23 | newName = ATTR_NAME_MAP[name];
24 | didNormalize = true;
25 | }
26 | normalized[newName] = attributes[name];
27 | }
28 | return didNormalize ? normalized : attributes;
29 | }
30 |
31 | export default normalizeAttributes;
32 |
--------------------------------------------------------------------------------
/src/editor/helpers/styleToCSS.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {isUnitlessNumber} from 'react-dom/lib/CSSProperty';
4 |
5 | type StyleDescr = {[key: string]: number | string};
6 |
7 | const VENDOR_PREFIX = /^(moz|ms|o|webkit)-/;
8 | const NUMERIC_STRING = /^\d+$/;
9 | const UPPERCASE_PATTERN = /([A-Z])/g;
10 |
11 | // Lifted from: https://github.com/facebook/react/blob/master/src/renderers/dom/shared/CSSPropertyOperations.js
12 | function processStyleName(name: string): string {
13 | return name
14 | .replace(UPPERCASE_PATTERN, '-$1')
15 | .toLowerCase()
16 | .replace(VENDOR_PREFIX, '-$1-');
17 | }
18 |
19 | // Lifted from: https://github.com/facebook/react/blob/master/src/renderers/dom/shared/dangerousStyleValue.js
20 | function processStyleValue(name: string, value: number | string): string {
21 | let isNumeric;
22 | if (typeof value === 'string') {
23 | isNumeric = NUMERIC_STRING.test(value);
24 | } else {
25 | isNumeric = true;
26 | value = String(value);
27 | }
28 | if (!isNumeric || value === '0' || isUnitlessNumber[name] === true) {
29 | return value;
30 | } else {
31 | return value + 'px';
32 | }
33 | }
34 |
35 | function styleToCSS(styleDescr: StyleDescr): string {
36 | return Object.keys(styleDescr).map((name) => {
37 | let styleValue = processStyleValue(name, styleDescr[name]);
38 | let styleName = processStyleName(name);
39 | return `${styleName}: ${styleValue}`;
40 | }).join('; ');
41 | }
42 |
43 | export default styleToCSS;
44 |
--------------------------------------------------------------------------------
/src/editor/toolBar/alignmentControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import StyleButton from "./styleButton"
3 | const AlignmentControls = (props) => {
4 | const {editorState,lang} = props;
5 | const selection = editorState.getSelection();
6 | const blockType = editorState.getCurrentContent().getBlockForKey(selection.getStartKey()).getType();
7 | const BLOCK_TYPES = [
8 | {
9 | text:lang.alignLeft,
10 | label: "editor_alignment_left",
11 | style: 'left'
12 | }, {
13 | text:lang.alignCenter,
14 | label: "editor_alignment_center",
15 | style: 'center'
16 | }, {
17 | text:lang.alignRight,
18 | label: "editor_alignment_right",
19 | style: 'right'
20 | }, {
21 | text:lang.alignJustify,
22 | label: "editor_alignment_justify",
23 | style: 'justify'
24 | }
25 | ];
26 | return (
27 |
28 | {BLOCK_TYPES.map((type, i) => {
29 | let button =
36 | return button;
37 | })}
38 |
39 | );
40 | };
41 | module.exports = AlignmentControls;
42 |
--------------------------------------------------------------------------------
/src/editor/toolBar/autoSave.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | class AutoSave extends Component {
3 | constructor(props) {
4 | super(props);
5 | }
6 | render() {
7 | return (
8 |
9 |
10 | {this.props.lang.autoSave}
11 |
12 |
13 | )
14 | }
15 | }
16 | module.exports = AutoSave;
17 |
--------------------------------------------------------------------------------
/src/editor/toolBar/autoSaveList.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {
3 | Modal,
4 | Button,
5 | Popconfirm,
6 | message,
7 | Table,
8 | Icon
9 | } from 'antd';
10 | import {PRO_COMMON} from '../../global/supports/publicDatas';
11 | import find from "lodash/find";
12 | class AutoSaveControls extends Component {
13 | constructor(props) {
14 | super(props);
15 | this.state = {
16 | visible: false,
17 | list: [],
18 | selectedRowKeys: [],
19 | selectedKeyName: ""
20 | },
21 | this.onAutoSaveToggle = this.onAutoSaveToggle.bind(this);
22 | this.handleCancel = this.handleCancel.bind(this);
23 | this.sendSavedItemToEditor = this.sendSavedItemToEditor.bind(this);
24 | this.doDelete = this.doDelete.bind(this);
25 | this.selectRow = this.selectRow.bind(this);
26 | }
27 |
28 | onAutoSaveToggle() {
29 | this.setState({visible: true, list: []});
30 | this.componentDidMount();
31 | }
32 | doDelete(text) {
33 | window.localStorage.removeItem("$d" + text);
34 | let currItem=find(this.state.list,item=>item.keyName==text)
35 | if (currItem.key===this.state.selectedRowKeys[0]) {
36 | this.state.selectedRowKeys=[];
37 | this.forceUpdate();
38 | }
39 | this.componentDidMount();
40 | }
41 | handleCancel(e) {
42 | // console.log(e);
43 | this.setState({visible: false});
44 | this.state.list = [];
45 | this.forceUpdate();
46 | }
47 | sendSavedItemToEditor() {
48 | this.setState({visible: false});
49 | let list = this.state.list.map((item) => {
50 | return item;
51 | });
52 | let content=PRO_COMMON.localDB.getter("$d"+this.state.selectedKeyName);//window.localStorage.getItem("$d"+this.state.selectedKeyName);
53 | //console.log("content",content)
54 | this.props.receiveSavedItem(content);
55 | this.state.list = [];
56 | this.forceUpdate();
57 | }
58 | componentDidMount() {
59 | //console.log("componentDidMount!");
60 | let itemList = [];
61 | for (var i = 0; i < localStorage.length; i++) {
62 | let keyName = localStorage.key(i);
63 | if (!~ keyName.lastIndexOf("$d")) {
64 | continue;
65 | }
66 | //console.log(keyName);
67 | itemList.push({keyName: keyName.replace("$d","")})
68 | }
69 |
70 | PRO_COMMON.obj.refsKeyTo(itemList)
71 | if (!!itemList.length) {
72 | //console.log("itemList", itemList);
73 | this.setState({list: itemList});
74 | } else {
75 | this.setState({list: []});
76 | }
77 | }
78 | selectRow(record, index) {
79 | //console.log("selectRow!",record, index)
80 | this.state.selectedRowKeys = [this.state.list[index].key];
81 | this.state.selectedKeyName = this.state.list[index].keyName;
82 | this.forceUpdate();
83 | }
84 | render() {
85 | let className = 'RichEditor-styleButton';
86 | let that = this;
87 |
88 | const columns = [
89 | {
90 | title: this.props.lang.previewMsg,
91 | dataIndex: 'keyName',
92 | key: 'keyName',
93 | render: (text, record, index) => (text + "...")
94 | }, {
95 | title: '',
96 | key: 'operation',
97 | render: (text, record) => (
98 | this.doDelete(record.keyName)}>{this.props.lang.deleteDraftItem}
99 | )
100 | }
101 | ];
102 |
103 | const rowSelection = {
104 | selectedRowKeys: that.state.selectedRowKeys,
105 | onChange: (selectedRowKeys, selectedRows) => {
106 | //console.log("onChange", selectedRowKeys);
107 | that.state.selectedRowKeys = selectedRowKeys;
108 | that.forceUpdate();
109 | },
110 | onSelect: function(record, selected, selectedRows) {
111 | //console.log("onSelect", record.keyName);
112 | that.state.selectedKeyName = record.keyName;
113 | },
114 | type: "radio"
115 | };
116 | return (
117 |
118 |
119 |
120 |
121 |
122 |
{this.props.lang.cancelText} < /Button>,
130 |
131 | {this.props.lang.OKText}
132 | ]}>
133 | {this.props.lang.draftCautionMsg}
140 |
141 |
142 | )
143 | }
144 | }
145 | module.exports = AutoSaveControls;
146 |
--------------------------------------------------------------------------------
/src/editor/toolBar/blockSelectorControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {Popconfirm,Icon} from 'antd';
3 | class RemoveStyleControls extends Component {
4 | constructor(props) {
5 | super(props);
6 | }
7 | render() {
8 | let className = 'RichEditor-styleButton';
9 | return (
10 |
11 |
12 |
13 |
14 |
15 | )
16 | }
17 | }
18 | module.exports = RemoveStyleControls;
19 |
--------------------------------------------------------------------------------
/src/editor/toolBar/blockStyleControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import StyleButton from "./styleButton"
3 | const BlockStyleControls = (props) => {
4 | const {editorState,lang} = props;
5 | const selection = editorState.getSelection();
6 | const blockType = editorState.getCurrentContent().getBlockForKey(selection.getStartKey()).getType();
7 | const BLOCK_TYPES = [
8 | {
9 | text:lang.H1,
10 | label: "editor_H1",
11 | style: 'header-one'
12 | }, {
13 | text:lang.H2,
14 | label: "editor_H2",
15 | style: 'header-two'
16 | }, {
17 | text:lang.H3,
18 | label: "editor_H3",
19 | style: 'header-three'
20 | }, {
21 | text:lang.H4,
22 | label: "editor_H4",
23 | style: 'header-four'
24 | }, {
25 | text:lang.refs,
26 | label: "editor_refs",
27 | style: 'blockquote'
28 | }, {
29 | text:lang.ul,
30 | label: "editor_ul",
31 | style: 'unordered-list-item'
32 | }, {
33 | text:lang.ol,
34 | label: "editor_ol",
35 | style: 'ordered-list-item'
36 | }, {
37 | text:lang.pre,
38 | label: "editor_pre",
39 | style: 'code-block'
40 | }
41 | ];
42 | return (
43 |
44 | {BLOCK_TYPES.map((type, i) => {
45 | let button =
52 | return button;
53 | })}
54 |
55 | );
56 | };
57 | module.exports = BlockStyleControls;
58 |
--------------------------------------------------------------------------------
/src/editor/toolBar/colorButton.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 |
3 | import colorStyleMap from "../config/colorStyleMap"
4 |
5 | class ColorButton extends Component {
6 | constructor(props) {
7 | super(props);
8 | this.onToggle = (e) => {
9 | e.preventDefault();
10 | this.props.onToggle(this.props.style);
11 | };
12 | }
13 |
14 | render() {
15 | const styles = {
16 | editor: {
17 | borderTop: '1px solid #ddd',
18 | cursor: 'text',
19 | fontSize: 16,
20 | marginTop: 20,
21 | minHeight: 400,
22 | paddingTop: 20
23 | },
24 | controls: {
25 | fontFamily: '\'Helvetica\', sans-serif',
26 | fontSize: 14,
27 | marginBottom: 10,
28 | userSelect: 'none'
29 | },
30 | ColorButton: {
31 | color: '#999',
32 | cursor: 'pointer',
33 | marginRight: 16,
34 | padding: '2px 0'
35 | },
36 | root: {
37 | fontFamily: '\'Georgia\', serif',
38 | padding: 20,
39 | width: 600
40 | },
41 | buttons: {
42 | marginBottom: 10
43 | },
44 | urlInputContainer: {
45 | marginBottom: 10
46 | },
47 | urlInput: {
48 | fontFamily: '\'Georgia\', serif',
49 | marginRight: 10,
50 | padding: 3
51 | },
52 | editor: {
53 | border: '1px solid #ccc',
54 | cursor: 'text',
55 | minHeight: 80,
56 | padding: 10
57 | },
58 | button: {
59 | marginTop: 10,
60 | textAlign: 'center'
61 | },
62 | link: {
63 | color: 'blue',
64 | textDecoration: 'underline'
65 | }
66 | };
67 |
68 | let style = Object.assign({}, styles.ColorButton, (this.props.active
69 | ? colorStyleMap[this.props.style]
70 | : {}));
71 | let className = 'RichEditor-styleButton';
72 | return (
73 |
74 |
80 | {this.props.label}
81 |
82 | {(() => {
83 | if (!!this.props.split) {
84 | return {this.props.split} ;
85 | }
86 | })()}
87 |
88 | )
89 | };
90 | }
91 | module.exports = ColorButton;
92 |
--------------------------------------------------------------------------------
/src/editor/toolBar/colorControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import ColorButton from "./colorButton"
3 | import {colorStyleMap} from "../utils/colorConfig"
4 | class ColorControls extends Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 | render() {
9 | let currentStyle = this.props.editorState.getCurrentInlineStyle();
10 | let COLORS = Object.keys(colorStyleMap).map(item => {
11 | return {label: ' ', alias: item, style: item}
12 | });
13 | return (
14 |
17 | {COLORS.map((type, i) => )}
26 |
27 | );
28 | }
29 | }
30 | module.exports = ColorControls;
31 |
--------------------------------------------------------------------------------
/src/editor/toolBar/cookieControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {Icon} from "antd"
3 |
4 | class OpenFull extends Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 | render() {
9 | return (
10 |
11 |
12 | {this.props.coverTitle}
13 |
14 |
15 | )
16 | }
17 | }
18 | class AutoSave extends Component {
19 | constructor(props) {
20 | super(props);
21 | }
22 | render() {
23 | return (
24 |
25 |
26 | {this.props.lang.autoSave}
27 |
28 |
29 | )
30 | }
31 | };
32 | class SourceEditor extends Component {
33 | constructor(props) {
34 | super(props);
35 | }
36 | render() {
37 | return (
38 |
39 |
40 | {this.props.coverTitle}
41 |
42 |
43 | )
44 | }
45 | };
46 | module.exports = {
47 | OpenFull,
48 | AutoSave,
49 | SourceEditor
50 | };
51 |
--------------------------------------------------------------------------------
/src/editor/toolBar/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | ImgStyleControls :require ("./mediaImageUploader"),
3 | VideoStyleControls :require ("./medioVideoUploader"),
4 | AudioStyleControls :require ("./medioAudioUploader"),
5 | AutoSaveControls :require ("./autoSaveList"),
6 | BlockStyleControls :require ("./BlockStyleControls"),
7 | RemoveStyleControls :require ("./removeStyleControls"),
8 | InlineStyleControls :require ("./inlineStyleControls"),
9 | ColorControls :require ("./colorControls"),
10 | PasteNoStyleControls :require ("./pasteNoStyleControls"),
11 | AutoSave :require ("./autoSave")
12 | };
13 |
--------------------------------------------------------------------------------
/src/editor/toolBar/inlineStyleControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import StyleButton from "./styleButton"
3 | class InlineStyleControls extends Component {
4 | constructor(props) {
5 | super(props);
6 | }
7 | render() {
8 | const {editorState,onToggle,lang} = this.props;
9 | const INLINE_STYLES = [
10 | {
11 | text: lang.textBold,
12 | style: 'BOLD',
13 | label: "editor_b"
14 | }, {
15 | text: lang.textItalic,
16 | style: 'ITALIC',
17 | label: "editor_i"
18 | }, {
19 | text: lang.textUnderline,
20 | style: 'UNDERLINE',
21 | label: "editor_u"
22 | }, {
23 | text: lang.textCode,
24 | style: 'CODE',
25 | label: "editor_e"
26 | }
27 | ];
28 | let currentStyle = editorState
29 | ? editorState.getCurrentInlineStyle()
30 | : {};
31 | return (
32 |
33 | {INLINE_STYLES.map((type, i) => )}
40 |
41 | )
42 | }
43 | }
44 | module.exports = InlineStyleControls;
45 |
--------------------------------------------------------------------------------
/src/editor/toolBar/medioAudioUploader.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {
3 | Upload,
4 | Modal,
5 | Button,
6 | Popconfirm,
7 | Form,
8 | Input,
9 | message,
10 | Icon
11 | } from 'antd';
12 | import {UploadImage} from '../../global/components/businessComponents';
13 | class AudioStyleControls extends Component {
14 | constructor(props) {
15 | super(props);
16 | this.state = {
17 | visible: false,
18 | audios: []
19 | },
20 | this.onAudioToggle = this.onAudioToggle.bind(this);
21 | this.sendAudioToEditor = this.sendAudioToEditor.bind(this);
22 | this.handleCancel = this.handleCancel.bind(this);
23 | this.getAudioObject = this.getAudioObject.bind(this);
24 | }
25 |
26 | getAudioObject(fileObj) {
27 | this.state.audios = this.state.audios.concat(fileObj);
28 | if (!!this.state.audios) {
29 | this.setState({disabled: false});
30 | }
31 | this.forceUpdate();
32 | }
33 |
34 | onAudioToggle() {
35 | this.setState({visible: true, disabled: true,audios : []})
36 | }
37 |
38 | sendAudioToEditor() {
39 | this.setState({visible: false});
40 | let audios = this.state.audios.map((item) => {
41 | return item;
42 | });
43 | this.props.receiveAudio(audios);
44 | this.state.audios = [];
45 | this.forceUpdate();
46 | }
47 |
48 | handleCancel(e) {
49 | // console.log(e);
50 | this.setState({visible: false});
51 | this.state.audios = [];
52 | this.forceUpdate();
53 | }
54 |
55 | render() {
56 | let className = 'RichEditor-styleButton';
57 | let that = this;
58 | return (
59 |
60 |
61 |
62 |
63 | {this.props.lang.cancelText} < /Button>, {this.props.lang.OKText} ]}>
70 |
79 |
80 |
81 | )
82 | }
83 | }
84 | module.exports = AudioStyleControls;
85 |
--------------------------------------------------------------------------------
/src/editor/toolBar/medioVideoUploader.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {
3 | Upload,
4 | Modal,
5 | Button,
6 | Popconfirm,
7 | Form,
8 | Input,
9 | message,
10 | Icon
11 | } from 'antd';
12 | import {UploadImage} from '../../global/components/businessComponents';
13 | class VideoStyleControls extends Component {
14 | constructor(props) {
15 | super(props);
16 | this.state = {
17 | visible: false,
18 | videos: []
19 | };
20 | this.onVideoToggle = this.onVideoToggle.bind(this);
21 |
22 | this.handleCancel = this.handleCancel.bind(this);
23 | this.getVideoObject = this.getVideoObject.bind(this);
24 | this.sendVideoToEditor = this.sendVideoToEditor.bind(this);
25 | }
26 |
27 | getVideoObject(fileObj) {
28 | this.state.videos = this.state.videos.concat(fileObj);
29 | if (!!this.state.videos) {
30 | this.setState({disabled: false})
31 | }
32 | this.forceUpdate();
33 | }
34 |
35 | sendVideoToEditor() {
36 | this.setState({visible: false});
37 | let videos = this.state.videos.map((item) => {
38 | return item;
39 | });
40 | this.props.receiveVideo(videos);
41 | this.state.videos = [];
42 | this.forceUpdate();
43 | }
44 |
45 | onVideoToggle() {
46 | this.setState({visible: true, disabled: true,videos : []})
47 | }
48 |
49 | handleCancel(e) {
50 | // console.log(e);
51 | this.setState({visible: false});
52 | this.state.videos = [];
53 | this.forceUpdate();
54 | }
55 |
56 | render() {
57 | let className = 'RichEditor-styleButton';
58 | let that = this;
59 | return (
60 |
61 |
62 |
63 |
64 | {this.props.lang.cancelText} , {this.props.lang.OKText} ]}>
71 |
80 |
81 |
82 | )
83 | }
84 | }
85 |
86 | module.exports = VideoStyleControls;
87 |
--------------------------------------------------------------------------------
/src/editor/toolBar/pasteNoStyleControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import ReactDom from 'react-dom';
3 | import {
4 | Modal,
5 | Button,
6 | Input,
7 | Icon
8 | } from 'antd';
9 | class PasteNoStyleControls extends Component {
10 | constructor(props) {
11 | super(props);
12 | this.state = {
13 | visible: false,
14 | plantext: ""
15 | };
16 | this.onTextToggle = this.onTextToggle.bind(this);
17 | this.pasteContent = this.pasteContent.bind(this);
18 | this.handleCancel = this.handleCancel.bind(this);
19 | this.sendTextToEditor = this.sendTextToEditor.bind(this);
20 | }
21 | pasteContent(e){
22 | this.state.plantext = e.target.value;
23 | this.forceUpdate();
24 | setTimeout(() => {
25 | if (!!this.state.plantext) {
26 | this.setState({disabled: false})
27 | }
28 | }, 100);
29 | }
30 | sendTextToEditor() {
31 | let text=this.state.plantext+"";
32 | this.props.receiveText(text);
33 | this.setState({visible: false,plantext: ""})
34 | }
35 |
36 | onTextToggle() {
37 | this.setState({visible: true, disabled: true,plantext : ""})
38 | // let that=this;
39 | // setTimeout(()=>{
40 | // console.log("this.refs.nostyletext",that.refs.noStyleText)
41 | // ReactDom.findDOMNode(that.refs.noStyleText).focus();
42 | // },1000);
43 | }
44 |
45 | handleCancel(e) {
46 | // console.log(e);
47 | this.setState({visible: false});
48 | this.state.plantext = "";
49 | this.forceUpdate();
50 | }
51 | componentDidMount(){
52 | }
53 | render() {
54 | let className = 'RichEditor-styleButton';
55 | let that = this;
56 | return (
57 |
58 |
59 |
60 |
61 |
62 |
63 | {that.props.lang.cancelText} < /Button>, {that.props.lang.OKText} ]}>
71 |
72 |
73 |
74 | )
75 | }
76 | }
77 |
78 | module.exports = PasteNoStyleControls;
79 |
--------------------------------------------------------------------------------
/src/editor/toolBar/removeStyleControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {Popconfirm,Icon} from 'antd';
3 | class RemoveStyleControls extends Component {
4 | constructor(props) {
5 | super(props);
6 | }
7 | render() {
8 | let className = 'RichEditor-styleButton';
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | )
18 | }
19 | }
20 | module.exports = RemoveStyleControls;
21 |
--------------------------------------------------------------------------------
/src/editor/toolBar/styleButton.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {Icon} from "antd"
3 | class StyleButton extends React.Component {
4 | constructor() {
5 | super();
6 | this.onToggle = (e) => {
7 | e.preventDefault();
8 | this.props.onToggle(this.props.style);
9 | };
10 | }
11 |
12 | render() {
13 | let className = 'RichEditor-styleButton';
14 | if (this.props.active) {
15 | className += ' RichEditor-activeButton ant-btn ant-btn-primary ant-btn-icon-only ';
16 | }
17 |
18 | return (
19 |
20 |
21 |
22 |
23 | {(() => {
24 | if (!!this.props.split) {
25 | return {this.props.split} ;
26 | }
27 | })()}
28 |
29 | );
30 | }
31 | }
32 | module.exports = StyleButton;
33 |
--------------------------------------------------------------------------------
/src/editor/toolBar/undoredoControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {Icon} from "antd"
3 |
4 | class undoRedo extends Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 | render() {
9 | let className = 'RichEditor-styleButton';
10 | return (
11 |
12 | this.props.onToggle("undo")} title={this.props.lang.undo}>
13 |
14 |
15 | this.props.onToggle("redo")} title={this.props.lang.redo}>
16 |
17 |
18 |
19 | )
20 | }
21 | };
22 | module.exports = undoRedo;
23 |
--------------------------------------------------------------------------------
/src/editor/toolBar/urlControls.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {Tooltip, Icon} from "antd"
3 | class AddUrl extends Component {
4 | constructor(props) {
5 | super(props);
6 | }
7 | render() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | )
15 | }
16 | }
17 |
18 | class CloseUrl extends Component {
19 | constructor(props) {
20 | super(props);
21 | }
22 | render() {
23 | return (
24 |
25 |
26 |
27 |
28 |
29 | )
30 | }
31 | }
32 |
33 | module.exports = {
34 | AddUrl,
35 | CloseUrl
36 | };
37 |
--------------------------------------------------------------------------------
/src/editor/utils/ExtendedRichUtils.js:
--------------------------------------------------------------------------------
1 | import { Modifier, EditorState, RichUtils } from 'draft-js';
2 | import getCurrentlySelectedBlock from './getCurrentlySelectedBlock';
3 |
4 | export const ALIGNMENTS = {
5 | CENTER: 'center',
6 | JUSTIFY: 'justify',
7 | LEFT: 'left',
8 | RIGHT: 'right'
9 | };
10 |
11 | export const ALIGNMENT_DATA_KEY = 'textAlignment';
12 |
13 | const ExtendedRichUtils = Object.assign({}, RichUtils, {
14 | // Largely copied from RichUtils' `toggleBlockType`
15 | toggleAlignment(editorState, alignment) {
16 | const { content, currentBlock, hasAtomicBlock, target } = getCurrentlySelectedBlock(editorState);
17 | // console.log("ExtendedRichUtils content, currentBlock, hasAtomicBlock, target",content, currentBlock, hasAtomicBlock, target)
18 | if (hasAtomicBlock) {
19 | return editorState;
20 | }
21 |
22 | const blockData = currentBlock.getData();
23 | // console.log("ExtendedRichUtils blockData,alignment",blockData,alignment)
24 | let keyName=blockData.get(ALIGNMENT_DATA_KEY);
25 | // console.log("ExtendedRichUtils blockData.get,keyName",ALIGNMENT_DATA_KEY,keyName)
26 | const alignmentToSet = ((!!blockData) && (keyName === alignment)) ?
27 | undefined :
28 | alignment;
29 | // console.log("ExtendedRichUtils alignmentToSet",alignmentToSet)
30 | // console.log("ExtendedRichUtils content",content)
31 | // console.log("ExtendedRichUtils target",target)
32 | // console.log("ExtendedRichUtils ALIGNMENT_DATA_KEY",ALIGNMENT_DATA_KEY)
33 | // console.log("ExtendedRichUtils alignmentToSet",alignmentToSet)
34 | let alignBlockData=new Map();
35 | alignBlockData.set(ALIGNMENT_DATA_KEY,alignmentToSet);
36 | // console.log("ExtendedRichUtils alignBlockData",alignBlockData);
37 | // let newBlockData=Modifier.mergeBlockData(content, target,alignBlockData );
38 | let newBlockData=Modifier.setBlockData(content, target,alignBlockData );
39 | // console.log("ExtendedRichUtils newBlockData",newBlockData);
40 | return EditorState.push(
41 | editorState,
42 | newBlockData,
43 | 'change-block-type'
44 | );
45 | },
46 |
47 | /*
48 | * An extension of the default split block functionality, originally pulled from
49 | * https://github.com/facebook/draft-js/blob/master/src/component/handlers/edit/commands/keyCommandInsertNewline.js
50 | *
51 | * This version ensures that the text alignment is copied from the previously selected block.
52 | */
53 | splitBlock(editorState) {
54 | // Original split logic
55 | const contentState = Modifier.splitBlock(
56 | editorState.getCurrentContent(),
57 | editorState.getSelection()
58 | );
59 | const splitState = EditorState.push(editorState, contentState, 'split-block');
60 |
61 | // Assign alignment if previous block has alignment. Note that `currentBlock` is the block that was selected
62 | // before the split.
63 | const { currentBlock } = getCurrentlySelectedBlock(editorState);
64 | const alignment = currentBlock.getData().get(ALIGNMENT_DATA_KEY);
65 | if (alignment) {
66 | return ExtendedRichUtils.toggleAlignment(splitState, alignment);
67 | } else {
68 | return splitState;
69 | }
70 | }
71 | });
72 |
73 | export default ExtendedRichUtils;
74 |
--------------------------------------------------------------------------------
/src/editor/utils/colorConfig.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | colorStyleMap: {
3 | grapeFruit1: {
4 | color: '#ED5565'
5 | },
6 | grapeFruit2: {
7 | color: '#Da4453'
8 | },
9 | bitterSweet1: {
10 | color: '#fc6e51'
11 | },
12 | bitterSweet2: {
13 | color: '#e9573f'
14 | },
15 | sunFlower1: {
16 | color: '#ffce54'
17 | },
18 | sunFlower2: {
19 | color: '#f6bb42'
20 | },
21 | grass1: {
22 | color: '#a0d468'
23 | },
24 | grass2: {
25 | color: '#bcc152'
26 | },
27 | mint1: {
28 | color: '#48cfad'
29 | },
30 | mint2: {
31 | color: '#37bc9b'
32 | },
33 | aqua1: {
34 | color: '#4fc1e9'
35 | },
36 | aqua2: {
37 | color: '#38afda'
38 | },
39 | blueJeans1: {
40 | color: '#5d9cec'
41 | },
42 | blueJeans2: {
43 | color: '#4a89dc'
44 | },
45 | lavander1: {
46 | color: '#ac92ec'
47 | },
48 | lavander2: {
49 | color: '#967adc'
50 | },
51 | mediumGray1: {
52 | color: '#ccd1d9'
53 | },
54 | mediumGray2: {
55 | color: '#aab2bd'
56 | },
57 | darkGray1: {
58 | color: '#656d78'
59 | },
60 | darkGray2: {
61 | color: '#434a54'
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/editor/utils/getCurrentlySelectedBlock.js:
--------------------------------------------------------------------------------
1 | const getCurrentlySelectedBlock = (editorState) => {
2 | const selection = editorState.getSelection();
3 | const startKey = selection.getStartKey();
4 | let endKey = selection.getEndKey();
5 | const content = editorState.getCurrentContent();
6 | let target = selection;
7 |
8 | // Triple-click can lead to a selection that includes offset 0 of the
9 | // following block. The `SelectionState` for this case is accurate, but
10 | // we should avoid toggling block type for the trailing block because it
11 | // is a confusing interaction.
12 | if (startKey !== endKey && selection.getEndOffset() === 0) {
13 | const blockBefore = content.getBlockBefore(endKey);
14 | if (!blockBefore) {
15 | throw new Error('Got unexpected null or undefined');
16 | }
17 |
18 | endKey = blockBefore.getKey();
19 | target = target.merge({
20 | anchorKey: startKey,
21 | anchorOffset: selection.getStartOffset(),
22 | focusKey: endKey,
23 | focusOffset: blockBefore.getLength(),
24 | isBackward: false
25 | });
26 | }
27 |
28 | const hasAtomicBlock = content.getBlockMap()
29 | .skipWhile((_, k) => k !== startKey)
30 | .takeWhile((_, k) => k !== endKey)
31 | .some(v => v.getType() === 'atomic');
32 |
33 | const currentBlock = content.getBlockForKey(startKey);
34 |
35 | return {
36 | content,
37 | currentBlock,
38 | hasAtomicBlock,
39 | target
40 | };
41 | };
42 |
43 | export default getCurrentlySelectedBlock;
--------------------------------------------------------------------------------
/src/editor/utils/index.js:
--------------------------------------------------------------------------------
1 | export {default as stateFromElement} from './stateFromElement/main';//https://github.com/sstur/draft-js-import-element/blob/9a989ed7d2f7a8453cc6ca1cfbab9754740e6e18/src/stateFromElement.js
2 | export {default as stateFromHTML} from './stateFromHTML/main';
3 | export {default as stateToHTML} from './stateToHTML/main';//note:from https://github.com/sstur/draft-js-export-html/blob/d41aa2f1ff633889b1bd361c5d60c7a5d7b1e531/src/stateToHTML.js
4 | export {default as stateFromMD} from './stateFromMD/main';
5 | export {default as stateToMD} from './stateToMD/main';
6 |
--------------------------------------------------------------------------------
/src/editor/utils/stateFromElement/replaceTextWithMeta.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import type {IndexedSeq} from 'immutable';
4 |
5 | type TextFragment = {
6 | text: string;
7 | characterMeta: IndexedSeq;
8 | };
9 |
10 | export default function replaceTextWithMeta(
11 | subject: TextFragment,
12 | searchText: string,
13 | replaceText: string
14 | ): TextFragment {
15 | let {text, characterMeta} = subject;
16 | let searchTextLength = searchText.length;
17 | let replaceTextLength = replaceText.length;
18 | let resultTextParts: Array = [];
19 | // Get empty set of same kind as characterMeta.
20 | let resultCharMeta = characterMeta.slice(0, 0);
21 | let lastEndIndex = 0;
22 | let index = text.indexOf(searchText);
23 | while (index !== -1) {
24 | resultTextParts.push(
25 | text.slice(lastEndIndex, index) + replaceText
26 | );
27 | resultCharMeta = resultCharMeta.concat(
28 | characterMeta.slice(lastEndIndex, index),
29 | // Use the metadata of the first char we are replacing.
30 | repeatSeq(characterMeta.slice(index, index + 1), replaceTextLength)
31 | );
32 | lastEndIndex = index + searchTextLength;
33 | index = text.indexOf(searchText, lastEndIndex);
34 | }
35 | resultTextParts.push(
36 | text.slice(lastEndIndex)
37 | );
38 | resultCharMeta = resultCharMeta.concat(
39 | characterMeta.slice(lastEndIndex)
40 | );
41 | return {text: resultTextParts.join(''), characterMeta: resultCharMeta};
42 | }
43 |
44 | function repeatSeq(seq: IndexedSeq, count: number): IndexedSeq {
45 | let result = seq.slice(0, 0);
46 | while (count-- > 0) {
47 | result = result.concat(seq);
48 | }
49 | return result;
50 | }
51 |
--------------------------------------------------------------------------------
/src/editor/utils/stateFromHTML/main.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {stateFromElement} from '../index';
4 | import parseHTML from './parseHTML';
5 |
6 | import type {ContentState} from 'draft-js';
7 |
8 | type Options = {
9 | parser?: (html: string) => Element;
10 | };
11 |
12 | export default function stateFromHTML(html: string, options?: Options): ContentState {
13 | let parser = (options == null || options.parser == null) ? parseHTML : options.parser;
14 | let element = parser(html);
15 | return stateFromElement(element, options);
16 | }
17 |
--------------------------------------------------------------------------------
/src/editor/utils/stateFromHTML/parseHTML.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function parseHTML(html: string): Element {
4 | let doc;
5 | if (typeof DOMParser !== 'undefined') {
6 | let parser = new DOMParser();
7 | doc = parser.parseFromString(html, 'text/html');
8 | } else {
9 | doc = document.implementation.createHTMLDocument('');
10 | doc.documentElement.innerHTML = html;
11 | }
12 | return doc.body;
13 | }
14 |
--------------------------------------------------------------------------------
/src/editor/utils/stateFromMD/main.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import MarkdownParser from './MarkdownParser';
4 | import {stateFromElement} from '../index';
5 |
6 | import type {ContentState} from 'draft-js';
7 |
8 | export default function stateFromMarkdown(markdown: string): ContentState {
9 | // console.log("MarkdownParser:",stateFromMarkdown);
10 | let element = MarkdownParser.parse(markdown, {getAST: true});
11 | return stateFromElement(element);
12 | }
13 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/Constants.js:
--------------------------------------------------------------------------------
1 | export const BLOCK_TYPE = {
2 | // This is used to represent a normal text block (paragraph).
3 | UNSTYLED: 'unstyled',
4 | HEADER_ONE: 'header-one',
5 | HEADER_TWO: 'header-two',
6 | HEADER_THREE: 'header-three',
7 | HEADER_FOUR: 'header-four',
8 | HEADER_FIVE: 'header-five',
9 | HEADER_SIX: 'header-six',
10 | UNORDERED_LIST_ITEM: 'unordered-list-item',
11 | ORDERED_LIST_ITEM: 'ordered-list-item',
12 | BLOCKQUOTE: 'blockquote',
13 | PULLQUOTE: 'pullquote',
14 | CODE: 'code-block',
15 | ATOMIC: 'atomic',
16 | };
17 |
18 | export const ENTITY_TYPE = {
19 | LINK: 'LINK',
20 | IMAGE: 'IMAGE',
21 | VIDEO: 'VIDEO',
22 | AUDIO: 'AUDIO'
23 | };
24 |
25 | export const INLINE_STYLE = {
26 | BOLD: 'BOLD',
27 | CODE: 'CODE',
28 | SPAN: 'SPAN',
29 | ITALIC: 'ITALIC',
30 | STRIKETHROUGH: 'STRIKETHROUGH',
31 | UNDERLINE: 'UNDERLINE',
32 | };
33 |
34 | export default {
35 | BLOCK_TYPE,
36 | ENTITY_TYPE,
37 | INLINE_STYLE,
38 | };
39 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/callModifierForSelectedBlocks.js:
--------------------------------------------------------------------------------
1 | import {EditorState, SelectionState} from 'draft-js';
2 |
3 | import getSelectedBlocks from './getSelectedBlocks';
4 |
5 | /**
6 | * Calls a provided `modifier` function with a selection for each
7 | * selected block in the current editor selection. Passes through additional
8 | * arguments to the modifier.
9 | *
10 | * Note: At the moment it will retain the original selection and override
11 | * possible selection changes from modifiers
12 | *
13 | * @param {object} editorState The current draft.js editor state object
14 | *
15 | * @param {function} modifier A modifier function to be executed.
16 | * Must have the signature (editorState, selection, ...)
17 | *
18 | * @param {mixed} ...args Additional arguments to be passed through to the modifier
19 | *
20 | * @return {object} The new editor state
21 | */
22 | export default (editorState, modifier, ...args) => {
23 | const contentState = editorState.getCurrentContent();
24 | const currentSelection = editorState.getSelection();
25 |
26 | const startKey = currentSelection.getStartKey();
27 | const endKey = currentSelection.getEndKey();
28 | const startOffset = currentSelection.getStartOffset();
29 | const endOffset = currentSelection.getEndOffset();
30 |
31 | const isSameBlock = startKey === endKey;
32 | const selectedBlocks = getSelectedBlocks(contentState, startKey, endKey);
33 |
34 | let finalEditorState = editorState;
35 | selectedBlocks.forEach((block) => {
36 | const currentBlockKey = block.getKey();
37 | let selectionStart = startOffset;
38 | let selectionEnd = endOffset;
39 |
40 | if (currentBlockKey === startKey) {
41 | selectionStart = startOffset;
42 | selectionEnd = isSameBlock ? endOffset : block.getText().length;
43 | } else if (currentBlockKey === endKey) {
44 | selectionStart = isSameBlock ? startOffset : 0;
45 | selectionEnd = endOffset;
46 | } else {
47 | selectionStart = 0;
48 | selectionEnd = block.getText().length;
49 | }
50 |
51 | const selection = new SelectionState({
52 | anchorKey: currentBlockKey,
53 | anchorOffset: selectionStart,
54 | focusKey: currentBlockKey,
55 | focusOffset: selectionEnd,
56 | });
57 |
58 | finalEditorState = modifier(finalEditorState, selection, ...args);
59 | });
60 |
61 | return EditorState.forceSelection(finalEditorState, currentSelection);
62 | };
63 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/combineOrderedStyles.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | type Attributes = {[key: string]: string};
4 | type StyleDescr = {[key: string]: number | string};
5 | type RenderConfig = {
6 | element?: string;
7 | attributes?: Attributes;
8 | style?: StyleDescr;
9 | };
10 | type StyleMap = {[styleName: string]: RenderConfig};
11 | type StyleOrder = Array;
12 | type OrderedStyleMap = [StyleMap, StyleOrder];
13 |
14 | function combineOrderedStyles(
15 | customMap: ?StyleMap,
16 | defaults: OrderedStyleMap
17 | ): OrderedStyleMap {
18 | if (customMap == null) {
19 | return defaults;
20 | }
21 | let [defaultStyleMap, defaultStyleOrder] = defaults;
22 | let styleMap = Object.assign({},defaultStyleMap);//{...defaultStyleMap}
23 | let styleOrder = [...defaultStyleOrder];
24 | for (let styleName of Object.keys(customMap)) {
25 | if (defaultStyleMap.hasOwnProperty(styleName)) {
26 | let defaultStyles = defaultStyleMap[styleName];
27 | styleMap[styleName] =Object.assign({},defaultStyles,customMap[styleName]);// {...defaultStyles, ...customMap[styleName]};
28 | } else {
29 | styleMap[styleName] = customMap[styleName];
30 | styleOrder.push(styleName);
31 | }
32 | }
33 | return [styleMap, styleOrder];
34 | }
35 |
36 | export default combineOrderedStyles;
37 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/getEntityRanges.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 | import {OrderedSet, is} from 'immutable';
3 |
4 | import type {CharacterMetadata} from 'draft-js';
5 | import type {List} from 'immutable';
6 |
7 | type EntityKey = ?string;
8 | type Style = OrderedSet;
9 | type StyleRange = [string, Style];
10 | type EntityRange = [EntityKey, Array];
11 | export type CharacterMetaList = List;
12 |
13 | export const EMPTY_SET: Style = new OrderedSet();
14 |
15 | export default function getEntityRanges(
16 | text: string,
17 | charMetaList: CharacterMetaList
18 | ): Array {
19 | let charEntity: ?string = null;
20 | let prevCharEntity: ?string = null;
21 | let ranges: Array = [];
22 | let rangeStart = 0;
23 | for (let i = 0, len = text.length; i < len; i++) {
24 | prevCharEntity = charEntity;
25 | let meta: CharacterMetadata = charMetaList.get(i);
26 | charEntity = meta ? meta.getEntity() : null;
27 | if (i > 0 && charEntity !== prevCharEntity) {
28 | ranges.push([
29 | prevCharEntity,
30 | getStyleRanges(
31 | text.slice(rangeStart, i),
32 | charMetaList.slice(rangeStart, i)
33 | ),
34 | ]);
35 | rangeStart = i;
36 | }
37 | }
38 | ranges.push([
39 | charEntity,
40 | getStyleRanges(
41 | text.slice(rangeStart),
42 | charMetaList.slice(rangeStart)
43 | ),
44 | ]);
45 | return ranges;
46 | }
47 |
48 | function getStyleRanges(
49 | text: string,
50 | charMetaList: CharacterMetaList
51 | ): Array {
52 | let charStyle = EMPTY_SET;
53 | let prevCharStyle = EMPTY_SET;
54 | let ranges = [];
55 | let rangeStart = 0;
56 | for (let i = 0, len = text.length; i < len; i++) {
57 | prevCharStyle = charStyle;
58 | let meta = charMetaList.get(i);
59 | charStyle = meta ? meta.getStyle() : EMPTY_SET;
60 | if (i > 0 && !is(charStyle, prevCharStyle)) {
61 | ranges.push([text.slice(rangeStart, i), prevCharStyle]);
62 | rangeStart = i;
63 | }
64 | }
65 | ranges.push([text.slice(rangeStart), charStyle]);
66 | return ranges;
67 | }
68 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/getSelectedBlocks.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns an array of all `ContentBlock` instances within two block keys
3 | *
4 | * @param {object} contentState A draft.js `ContentState` instance
5 | * @param {string} anchorKey The block key to start searching from
6 | * @param {string} focusKey The block key until which to search
7 | *
8 | * @return {array} An array containing the found content blocks
9 | */
10 | export default (contentState, anchorKey, focusKey) => {
11 | const isSameBlock = anchorKey === focusKey;
12 | const startingBlock = contentState.getBlockForKey(anchorKey);
13 |
14 | if (!startingBlock) {
15 | return [];
16 | }
17 |
18 | let selectedBlocks = [startingBlock];
19 |
20 | if (!isSameBlock) {
21 | let blockKey = anchorKey;
22 |
23 | while (blockKey !== focusKey) {
24 | const nextBlock = contentState.getBlockAfter(blockKey);
25 |
26 | if (!nextBlock) {
27 | selectedBlocks = [];
28 | break;
29 | }
30 |
31 | selectedBlocks.push(nextBlock);
32 | blockKey = nextBlock.getKey();
33 | }
34 | }
35 |
36 | return selectedBlocks;
37 | };
38 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/main.js:
--------------------------------------------------------------------------------
1 | export * from './Constants';
2 | export {default as Constants} from './Constants';
3 |
4 | export {default as getEntityRanges} from './getEntityRanges';
5 |
6 | export type {CharacterMetaList} from './getEntityRanges';
7 |
8 | export {default as getSelectedBlocks} from './getSelectedBlocks';
9 | export {default as selectionContainsEntity} from './selectionContainsEntity';
10 | export {default as callModifierForSelectedBlocks} from './callModifierForSelectedBlocks';
11 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/normalizeAttributes.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | type Attributes = {[key: string]: string};
4 | type StringMap = {[key: string]: string};
5 |
6 | // Lifted from: https://github.com/facebook/react/blob/master/src/renderers/dom/shared/HTMLDOMPropertyConfig.js
7 | const ATTR_NAME_MAP: StringMap = {
8 | acceptCharset: 'accept-charset',
9 | className: 'class',
10 | htmlFor: 'for',
11 | httpEquiv: 'http-equiv',
12 | };
13 |
14 | function normalizeAttributes(attributes: ?Attributes) {
15 | if (attributes == null) {
16 | return attributes;
17 | }
18 | let normalized = {};
19 | let didNormalize = false;
20 | for (let name of Object.keys(attributes)) {
21 | let newName = name;
22 | if (ATTR_NAME_MAP.hasOwnProperty(name)) {
23 | newName = ATTR_NAME_MAP[name];
24 | didNormalize = true;
25 | }
26 | normalized[newName] = attributes[name];
27 | }
28 | return didNormalize ? normalized : attributes;
29 | }
30 |
31 | export default normalizeAttributes;
32 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/selectionContainsEntity.js:
--------------------------------------------------------------------------------
1 | import getSelectedBlocks from './getSelectedBlocks';
2 |
3 | export default (strategy) => (editorState, selection) => {
4 | const contentState = editorState.getCurrentContent();
5 | const currentSelection = selection || editorState.getSelection();
6 | const startKey = currentSelection.getStartKey();
7 | const endKey = currentSelection.getEndKey();
8 | const startOffset = currentSelection.getStartOffset();
9 | const endOffset = currentSelection.getEndOffset();
10 |
11 | const isSameBlock = startKey === endKey;
12 | const selectedBlocks = getSelectedBlocks(contentState, startKey, endKey);
13 | let entityFound = false;
14 |
15 | // We have to shift the offset to not get false positives when selecting
16 | // a character just before or after an entity
17 | const finalStartOffset = startOffset + 1;
18 | const finalEndOffset = endOffset - 1;
19 |
20 | selectedBlocks.forEach((block) => {
21 | strategy(
22 | block,
23 | (start, end) => {
24 | if (entityFound) {
25 | return;
26 | }
27 |
28 | const blockKey = block.getKey();
29 |
30 | if (isSameBlock && (end < finalStartOffset || start > finalEndOffset)) {
31 | return;
32 | } else if (blockKey === startKey && end < finalStartOffset) {
33 | return;
34 | } else if (blockKey === endKey && start > finalEndOffset) {
35 | return;
36 | }
37 |
38 | entityFound = true;
39 | }
40 | );
41 | });
42 |
43 | return entityFound;
44 | };
45 |
--------------------------------------------------------------------------------
/src/editor/utils/stateUtils/styleToCSS.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {isUnitlessNumber} from 'react-dom/lib/CSSProperty';
4 |
5 | type StyleDescr = {[key: string]: number | string};
6 |
7 | const VENDOR_PREFIX = /^(moz|ms|o|webkit)-/;
8 | const NUMERIC_STRING = /^\d+$/;
9 | const UPPERCASE_PATTERN = /([A-Z])/g;
10 |
11 | // Lifted from: https://github.com/facebook/react/blob/master/src/renderers/dom/shared/CSSPropertyOperations.js
12 | function processStyleName(name: string): string {
13 | return name
14 | .replace(UPPERCASE_PATTERN, '-$1')
15 | .toLowerCase()
16 | .replace(VENDOR_PREFIX, '-$1-');
17 | }
18 |
19 | // Lifted from: https://github.com/facebook/react/blob/master/src/renderers/dom/shared/dangerousStyleValue.js
20 | function processStyleValue(name: string, value: number | string): string {
21 | let isNumeric;
22 | if (typeof value === 'string') {
23 | isNumeric = NUMERIC_STRING.test(value);
24 | } else {
25 | isNumeric = true;
26 | value = String(value);
27 | }
28 | if (!isNumeric || value === '0' || isUnitlessNumber[name] === true) {
29 | return value;
30 | } else {
31 | return value + 'px';
32 | }
33 | }
34 |
35 | function styleToCSS(styleDescr: StyleDescr): string {
36 | return Object.keys(styleDescr).map((name) => {
37 | let styleValue = processStyleValue(name, styleDescr[name]);
38 | let styleName = processStyleName(name);
39 | return `${styleName}: ${styleValue}`;
40 | }).join('; ');
41 | }
42 |
43 | export default styleToCSS;
44 |
--------------------------------------------------------------------------------
/src/global/components/businessComponents.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by lizhen on 4/14/2016.
3 | */
4 | module.exports = {
5 | UploadImage: require('./businessComponents/UploadImage'),
6 | GroupUpload:require('./businessComponents/GroupUpload')
7 | };
8 |
--------------------------------------------------------------------------------
/src/global/supports/datas/base.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Administrator on 2016/5/20.
3 | */
4 | module.exports = {
5 | Config: {
6 | version: "2.1.3 (Beta)",
7 | server : {
8 | // ajax: 'http://192.168.110.239:8082/qlwb/' //测试服务器
9 | ajax: 'http://114.55.148.57:8083/' //正式(公网)服务器
10 | },
11 | watermarkImage: [{
12 | type: "white_small",
13 | tip: "白色小图",
14 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/white_small.png",
15 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS93aGl0ZV9zbWFsbC5wbmc="
16 | }, {
17 | type: "white_big",
18 | tip: "白色大图",
19 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/white_big.png",
20 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS93aGl0ZV9iaWcucG5n"
21 | }, {
22 | type: "gray_small",
23 | tip: "灰色小图",
24 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/gray_small.png",
25 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS9ncmF5X3NtYWxsLnBuZw=="
26 | }, {
27 | type: "gray_big",
28 | tip: "灰色大图",
29 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/gray_big.png",
30 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS9ncmF5X2JpZy5wbmc="
31 | }, {
32 | type: "black_small",
33 | tip: "黑色小图",
34 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/black_small.png",
35 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS9ibGFja19zbWFsbC5wbmc="
36 | }, {
37 | type: "black_big",
38 | tip: "黑色大图",
39 | value: "http://7xjl1j.com1.z0.glb.clouddn.com/black_big.png",
40 | valuebase64: "aHR0cDovLzd4amwxai5jb20xLnowLmdsYi5jbG91ZGRuLmNvbS9ibGFja19iaWcucG5n"
41 | }]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/global/supports/methods/public.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Administrator on 2016/5/5.
3 | * From Public function doing
4 | */
5 | import {ajax as AJAX} from './Request';
6 | import {QINIU_IMG_TOKEN_URL, QINIU_MANAGE_TOKEN_URL, QINIU_VIDEO_TOKEN_URL, QINIU_FILE_TOKEN_URL} from '../datas/url';
7 | module.exports = {
8 | supportMime: {
9 | image: [
10 | "image/jpeg", "image/png", "image/jpg", "image/gif", "image/webp"
11 | ],
12 | video: ["video/mp4"],
13 | audio: ["audio/mp4", "audio/mp3", "audio/mpeg"]
14 | },
15 | makeGuid: function() {
16 | var guid = "";
17 | for (var i = 1; i <= 32; i++) {
18 | var n = Math.floor(Math.random() * 16.0).toString(16);
19 | guid += n;
20 | if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
21 | guid += "-";
22 | }
23 | return guid;
24 | },
25 |
26 | nowTime: function() {
27 | let time = Date.parse(new Date()) / 1000;
28 | return time;
29 | },
30 |
31 | checkQiniu: {
32 |
33 | checkQiniuImgToken: function(key) {
34 |
35 | let timestamp = Date.parse(new Date()) / 1000;
36 | let last_qiniu_token_time = localStorage.getItem("last_qiniu_token_time_" + key);
37 | let mark = false;
38 |
39 | if (last_qiniu_token_time) {
40 | if ((timestamp - last_qiniu_token_time) < 3500) {
41 | //console.log("time not out ");
42 | mark = true;
43 | }
44 | }
45 | let qiniu_token = "";
46 | if (localStorage.getItem("qiniu_" + key + "_token") && mark) {
47 | qiniu_token = localStorage.getItem("qiniu_" + key + "_token");
48 | }
49 | return qiniu_token;
50 | },
51 | returnToken: function(uploadConfig={},key = 'image', params = {}) {
52 | if (Object.keys(uploadConfig).length==0) {
53 | return false;
54 | }
55 | let token = this.checkQiniuImgToken(key);
56 | token = !!token == true
57 | ? token
58 | : this.getQiniuToken(uploadConfig, key, params);
59 | return token;
60 | },
61 | getQiniuToken: function(uploadConfig,type = 'image', params) {
62 | //console.log("getQiniuToken");
63 | let token = "";
64 | let url;
65 | if (type == 'image') {
66 | url = uploadConfig.QINIU_IMG_TOKEN_URL;
67 | } else if (type == 'video') {
68 | url = uploadConfig.QINIU_VIDEO_TOKEN_URL;
69 | } else if (type == 'file') {
70 | url = uploadConfig.QINIU_FILE_TOKEN_URL;
71 | } else if (type == 'manage') {
72 | url = uploadConfig.QINIU_MANAGE_TOKEN_URL;
73 | } else {
74 | url = uploadConfig.QINIU_IMG_TOKEN_URL;
75 | }
76 | //console.log("token_url",url);
77 | AJAX.requestData({
78 | url: url,
79 | method: 'post',
80 | isAsync: true,
81 | defaultData: {}
82 | }, params, (data) => {
83 | //console.log(data); data = JSON.parse(data);
84 | token = data.uptoken;
85 | //console.log("token=", token);
86 | localStorage.setItem("qiniu_" + type + "_token", token);
87 | localStorage.setItem("last_qiniu_token_time_" + type, Date.parse(new Date()) / 1000);
88 | }, () => {
89 | //console.log("err:", err);
90 | return false;
91 | });
92 | return token;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/global/supports/publicDatas.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by lizhen on 4/14/2016.
3 | */
4 | //import PRO_MENU from 'datas/menu';
5 | //import PRO_RELEASE from 'datas/release';
6 | //import PRO_URL from 'datas/url';
7 | //import PRO_USER from 'datas/user';
8 | //import PRO_DOM_HELPER from 'methods/domHelper';
9 | //import PRO_REQUEST from 'methods/Request';
10 | //import PRO_COMMON from 'methods/common';
11 | //import PRO_QINIU from 'methods/public';
12 | //module.exports = {PRO_RELEASE, PRO_MENU, PRO_URL, PRO_USER, PRO_DOM_HELPER, PRO_REQUEST, PRO_COMMON, PRO_QINIU};
13 | module.exports = {
14 | PRO_BASE: require('./datas/base'),
15 | PRO_URL: require('./datas/url'),
16 | PRO_REQUEST: require('./methods/Request'),
17 | PRO_COMMON: require('./methods/common'),
18 | PRO_QINIU: require('./methods/public')
19 | };
20 |
--------------------------------------------------------------------------------
/src/global/supports/resources/blur.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/global/supports/resources/custom.css:
--------------------------------------------------------------------------------
1 | .openFullAll {
2 | position: fixed;
3 | top: 0;
4 | right: 0;
5 | bottom: 0;
6 | left: 0;
7 | z-index: 999;
8 | overflow: auto;
9 | }
10 |
11 | .watermark_grid {
12 | display: block;
13 | position: absolute;
14 | top: 0;
15 | background-repeat: no-repeat;
16 | }
17 |
18 | .watermark_grid span {
19 | display: inline-block;
20 | border: 1px dashed rgba(255, 255, 255, .2);
21 | cursor: pointer;
22 | }
23 |
24 | .editor-inline-image tips {
25 | font-size: 12px;
26 | position: absolute;
27 | right: 0;
28 | color: #aaa;
29 | }
30 | .uploadingImagies {
31 | text-align: center;
32 | }
33 | .uploadingImagies img{
34 | max-width: 100%;
35 | }
36 | .uploadingImagies a {
37 | font-size: 20px;
38 | position: relative;
39 | display: inherit;
40 | margin: 0 auto;
41 | }
42 | .breakImages>div {
43 | width: 100px;
44 | height: 100px;
45 | overflow: hidden;
46 | display: inline-block;
47 | margin: 10px 10px 0 0;
48 | background-clip: content-box;
49 | background-size: cover;
50 | background-repeat: no-repeat;
51 | background-position: center;
52 | border: 1px solid #E9E9E9;
53 | border-radius: 3px;
54 | overflow: hidden;
55 | }
56 |
--------------------------------------------------------------------------------
/src/global/supports/resources/default/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/src/global/supports/resources/default/iconfont.eot
--------------------------------------------------------------------------------
/src/global/supports/resources/default/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/src/global/supports/resources/default/iconfont.ttf
--------------------------------------------------------------------------------
/src/global/supports/resources/default/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leejaen/react-lz-editor/5097a8a57ac919afab3da11ad10e076bfdf4be24/src/global/supports/resources/default/iconfont.woff
--------------------------------------------------------------------------------
/src/global/supports/resources/iconfont.css:
--------------------------------------------------------------------------------
1 |
2 | @font-face {font-family: "iconfont";
3 | src: url('iconfont.eot?t=1479085947184'); /* IE9*/
4 | src: url('iconfont.eot?t=1479085947184#iefix') format('embedded-opentype'), /* IE6-IE8 */
5 | url('iconfont.woff?t=1479085947184') format('woff'), /* chrome, firefox */
6 | url('iconfont.ttf?t=1479085947184') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
7 | url('iconfont.svg?t=1479085947184#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .iconfont {
11 | font-family:"iconfont" !important;
12 | font-size:16px;
13 | font-style:normal;
14 | -webkit-font-smoothing: antialiased;
15 | -webkit-text-stroke-width: 0.2px;
16 | -moz-osx-font-smoothing: grayscale;
17 | }
18 |
19 | .icon-panorama_time:before { content: "\ea16"; }
20 |
21 | .icon-shangdian:before { content: "\ea01"; }
22 |
23 | .icon-yonghuzumingcheng:before { content: "\ea36"; }
24 |
25 | .icon-panorama_joinuser:before { content: "\ea18"; }
26 |
27 | .icon-panorama_joindevice:before { content: "\ea19"; }
28 |
29 | .icon-shangpin:before { content: "\e998"; }
30 |
31 | .icon-newsVerify:before { content: "\ea26"; }
32 |
33 | .icon-access_user:before { content: "\ea1d"; }
34 |
35 | .icon-xitong:before { content: "\ea1c"; }
36 |
37 | .icon-dropdown:before { content: "\ea0b"; }
38 |
39 | .icon-yidianhaoleibie:before { content: "\ea2e"; }
40 |
41 | .icon-unie60e:before { content: "\ea23"; }
42 |
43 | .icon-yidianhaowenzhang:before { content: "\ea30"; }
44 |
45 | .icon-empty:before { content: "\ea0d"; }
46 |
47 | .icon-lunbozutu:before { content: "\ea06"; }
48 |
49 | .icon-quanzi:before { content: "\e991"; }
50 |
51 | .icon-recycleNews:before { content: "\ea24"; }
52 |
53 | .icon-tiezi:before { content: "\e995"; }
54 |
55 | .icon-unie6672:before { content: "\e996"; }
56 |
57 | .icon-untitled22:before { content: "\e993"; }
58 |
59 | .icon-unie604:before { content: "\e932"; }
60 |
61 | .icon-untitled144:before { content: "\ea04"; }
62 |
63 | .icon-newsChannel1:before { content: "\ea27"; }
64 |
65 | .icon-quanziline:before { content: "\e992"; }
66 |
67 | .icon-piliangicon:before { content: "\ea08"; }
68 |
69 | .icon-yidianhaotiaomu:before { content: "\ea2f"; }
70 |
71 | .icon-huodong:before { content: "\e999"; }
72 |
73 | .icon-paixu:before { content: "\ea03"; }
74 |
75 | .icon-news:before { content: "\ea2a"; }
76 |
77 | .icon-jiangpai:before { content: "\ea1b"; }
78 |
79 | .icon-appclient:before { content: "\ea40"; }
80 |
81 | .icon-neirong:before { content: "\e994"; }
82 |
83 | .icon-paixu1:before { content: "\ea0e"; }
84 |
85 | .icon-newsComment:before { content: "\ea29"; }
86 |
87 | .icon-bumen:before { content: "\ea34"; }
88 |
89 | .icon-pinpai:before { content: "\ea02"; }
90 |
91 | .icon-newsChannel:before { content: "\ea28"; }
92 |
93 | .icon-yonghuxinxixian:before { content: "\ea07"; }
94 |
95 | .icon-panorama_app:before { content: "\ea1a"; }
96 |
97 | .icon-panorama_today:before { content: "\ea12"; }
98 |
99 | .icon-yaochi:before { content: "\ea09"; }
100 |
101 | .icon-gengxinupdated:before { content: "\ea21"; }
102 |
103 | .icon-panorama_version:before { content: "\ea14"; }
104 |
105 | .icon-wochuangjiande:before { content: "\ea38"; }
106 |
107 | .icon-ditu-copy-copy:before { content: "\e997"; }
108 |
109 | .icon-jingxuan-copy:before { content: "\ea05"; }
110 |
111 | .icon-yichu:before { content: "\ea0a"; }
112 |
113 | .icon-panorama_newboot:before { content: "\ea13"; }
114 |
115 | .icon-panorama:before { content: "\ea15"; }
116 |
117 | .icon-panorama_device:before { content: "\ea17"; }
118 |
119 | .icon-lunbotuzujian:before { content: "\ea39"; }
120 |
121 | .icon-order:before { content: "\ea0c"; }
122 |
123 | .icon-sort:before { content: "\ea10"; }
124 |
125 | .icon-zhanghuyuquanxian:before { content: "\ea32"; }
126 |
127 | .icon-panorama_action:before { content: "\ea11"; }
128 |
129 | .icon-yidianhaoshenhe:before { content: "\ea31"; }
130 |
131 | .icon-jiaosequanxian0101:before { content: "\ea1f"; }
132 |
133 | .icon-city:before { content: "\ea25"; }
134 |
135 | .icon-startpage:before { content: "\ea41"; }
136 |
137 | .icon-jiaosesheding:before { content: "\ea1e"; }
138 |
139 | .icon-chuangjianjiaose:before { content: "\ea22"; }
140 |
141 | .icon-yidianhao:before { content: "\ea2d"; }
142 |
143 | .icon-gongzuoxiang:before { content: "\ea20"; }
144 |
145 | .icon-grab:before { content: "\ea2c"; }
146 |
147 | .icon-draft:before { content: "\ea2b"; }
148 |
149 | .icon-channelpd-copy:before { content: "\ea33"; }
150 |
151 | .icon-bumen-copy:before { content: "\ea37"; }
152 |
153 | .icon-10106-copy:before { content: "\ea35"; }
154 |
155 | .icon-news_radar:before { content: "\ea49"; }
156 |
157 | .icon-news_radar_list:before { content: "\ea50"; }
158 |
159 | .icon-news_radar_comment:before { content: "\ea51"; }
160 |
--------------------------------------------------------------------------------
/src/global/supports/resources/system.less:
--------------------------------------------------------------------------------
1 | @import "custom.css";
2 | @import "customiconfont.less";
3 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = require('./editor/index');
3 | exports.LzEditor = require('./editor/index');
4 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Test from './test.jsx';
2 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 | module.exports = {
4 | //entry:path.resolve('','src/main.js'),
5 | resolve: {
6 | root: [
7 | path.resolve('./src/global/components'),
8 | path.resolve('./src/global/supports'),
9 | ],
10 | extensions: ['', '.js', '.jsx']
11 | },
12 | entry: [
13 | 'webpack/hot/dev-server',
14 | 'webpack-dev-server/client?http://localhost:8081',
15 | // path.resolve('', 'src/main.js')//for publish
16 | path.resolve('', 'src/test.jsx')//for text
17 | ],
18 | output: {
19 | path: path.resolve('', 'build'),
20 | filename: 'bundle.js'
21 | },
22 | module: {
23 | loaders: [{
24 | test: /.jsx?$/,
25 | loader: 'babel-loader',
26 | exclude: /node_modules/,
27 | query: {
28 | presets: ['es2015', 'react']
29 | }
30 | }, {
31 | test: /.js$/,
32 | loader: 'babel-loader',
33 | exclude: /node_modules/,
34 | query: {
35 | presets: ['es2015', 'react'],
36 | //compact: false
37 | },
38 | loaders: [
39 | 'babel?presets[]=react,presets[]=es2015,presets[]=stage-2'
40 | ]
41 | }, {
42 | test: /\.(jpg|png)$/,
43 | loader: "url?limit=8192"
44 | }, {
45 | test: /\.less$/,
46 | loader: 'style!css!less'
47 | }, {
48 | test: /\.css$/, // Only .css files
49 | loader: 'style!css' // Run both loaders
50 | }, {
51 | test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
52 | loader: "url-loader?limit=10000&mimetype=application/font-woff"
53 | }, {
54 | test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
55 | loader: "file-loader"
56 | }]
57 | },
58 | plugins: [
59 | new webpack.DefinePlugin({
60 | 'process.env.NODE_ENV': '"development"'
61 | }),
62 | new webpack.HotModuleReplacementPlugin()
63 | ]
64 | };
65 |
--------------------------------------------------------------------------------
/webpack.release.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 | var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
4 | module.exports = {
5 | resolve: {
6 | root: [
7 | path.resolve('./src/global/components'),
8 | path.resolve('./src/global/supports'),
9 | ],
10 | extensions: ['', '.js', '.jsx']
11 | },
12 | entry: [
13 | path.resolve('', 'src/test.jsx')
14 | ],
15 | output: {
16 | path: __dirname + '/release',
17 | filename: 'bundle.js',
18 | chunkFilename: '[id].[chunkhash:4].js'
19 | },
20 | module: {
21 | loaders: [{
22 | test: /.jsx?$/,
23 | loader: 'babel-loader',
24 | exclude: /node_modules/,
25 | query: {
26 | presets: ['es2015', 'react']
27 | }
28 | }, {
29 | test: /.js$/,
30 | loader: 'babel-loader',
31 | exclude: /node_modules/,
32 | query: {
33 | presets: ['es2015', 'react'],
34 | },
35 | loaders: [
36 | 'babel?presets[]=react,presets[]=es2015,presets[]=stage-2'
37 | ]
38 | }, {
39 | test: /\.(jpg|png)$/,
40 | loader: "url?limit=8192"
41 | }, {
42 | test: /\.less$/,
43 | loader: 'style!css!less'
44 | }, {
45 | test: /\.css$/, // Only .css files
46 | loader: 'style!css' // Run both loaders
47 | }, {
48 | test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
49 | loader: "url-loader?limit=10000&mimetype=application/font-woff"
50 | }, {
51 | test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
52 | loader: "file-loader"
53 | }]
54 | },
55 | plugins: [
56 | new webpack.DefinePlugin({
57 | 'process.env.NODE_ENV': JSON.stringify("production") //部署时用
58 | }),
59 | new webpack.optimize.DedupePlugin() //找相等或近似的模块,避免在最终生成的文件中出现重复的模块
60 | ]
61 | };
62 |
--------------------------------------------------------------------------------