dante2-editor 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.babelrc +20 -0
- data/.eslint +13 -0
- data/.gitignore +15 -0
- data/README.md +5 -1
- data/dante2.gemspec +2 -4
- data/{app → demo}/assets/index.html +2 -2
- data/{app → demo}/assets/license.html +1 -1
- data/{app → demo}/assets/options.html +1 -5
- data/{app → demo}/assets/store.json +0 -0
- data/demo/data/poc.js +9 -0
- data/demo/demo.js +9 -0
- data/demo/initialize.js +7 -0
- data/{app → demo}/styles/layout/layout.scss +0 -0
- data/{app → demo}/styles/layout/normalize.css +0 -0
- data/{app → demo}/styles/layout/scaffold.scss +0 -0
- data/{app → demo}/styles/layout/tooltips.scss +0 -0
- data/dist/Dante2.js +2995 -0
- data/dist/Dante2.min.js +3 -0
- data/dist/Dante2.min.js.map +1 -0
- data/dist/DanteStyles.css +2 -0
- data/dist/DanteStyles.css.map +1 -0
- data/dist/DanteStyles.js +102 -0
- data/dist/DanteStyles.min.js +2 -0
- data/dist/DanteStyles.min.js.map +1 -0
- data/dist/dante-vendors.js +48316 -0
- data/dist/dante-vendors.min.js +29 -0
- data/dist/dante-vendors.min.js.map +1 -0
- data/{app/styles/fonts/dante → dist/fonts}/dante.eot +0 -0
- data/{app/styles/fonts/dante → dist/fonts}/dante.svg +0 -0
- data/{app/styles/fonts/dante → dist/fonts}/dante.ttf +0 -0
- data/{app/styles/fonts/dante → dist/fonts}/dante.woff +0 -0
- data/{app/styles/fonts/dante → dist/fonts}/fontello.eot +0 -0
- data/{app/styles/fonts/dante → dist/fonts}/fontello.svg +0 -0
- data/{app/styles/fonts/dante → dist/fonts}/fontello.ttf +0 -0
- data/{app/styles/fonts/dante → dist/fonts}/fontello.woff +0 -0
- data/docs/app.css +430 -1
- data/docs/app.css.map +1 -1
- data/docs/app.js +62 -2
- data/docs/app.js.map +1 -1
- data/docs/dante-vendors.js +49513 -22
- data/docs/dante-vendors.js.map +1 -1
- data/docs/dante.css +1602 -1
- data/docs/dante.css.map +1 -1
- data/docs/dante.js +3310 -3
- data/docs/dante.js.map +1 -1
- data/docs/doc.html +3 -7
- data/docs/index.html +4 -4
- data/docs/license.html +3 -3
- data/docs/options.html +53 -0
- data/package.json +47 -17
- data/rb_lib/dante2-editor/rails.rb +15 -0
- data/{lib → rb_lib}/dante2-editor/version.rb +1 -1
- data/{lib → rb_lib}/dante2-editor.rb +0 -0
- data/src/components/blocks/embed.js +126 -0
- data/src/components/blocks/image.js +377 -0
- data/src/components/blocks/placeholder.js +68 -0
- data/src/components/blocks/video.js +80 -0
- data/src/components/dante.js +291 -0
- data/src/components/dante_editor.js +928 -0
- data/src/components/debug.js +104 -0
- data/src/components/decorators/link.js +64 -0
- data/src/components/popovers/addButton.js +318 -0
- data/src/components/popovers/image.js +188 -0
- data/src/components/popovers/link.js +107 -0
- data/src/components/popovers/toolTip.js +402 -0
- data/{app/utils/logger.coffee → src/components/wrapper.js} +0 -0
- data/{app → src}/images/dante/media-loading-placeholder.png +0 -0
- data/{app → src}/images/site/dante-demo.png +0 -0
- data/{app → src}/images/site/dante-editor-logo.png +0 -0
- data/{app → src}/images/site/github-logo.png +0 -0
- data/src/index.js +9 -0
- data/{app → src}/model/index.js +0 -0
- data/src/style.js +3 -0
- data/{app → src}/styles/dante/_animations.scss +0 -0
- data/{app → src}/styles/dante/_caption.scss +0 -0
- data/{app → src}/styles/dante/_debug.scss +0 -0
- data/{app → src}/styles/dante/_fonts.scss +0 -0
- data/{app → src}/styles/dante/_graf.scss +0 -0
- data/{app → src}/styles/dante/_icons.scss +0 -0
- data/{app → src}/styles/dante/_media.scss +0 -0
- data/{app → src}/styles/dante/_menu.scss +0 -0
- data/{app → src}/styles/dante/_needsorder.scss +0 -0
- data/{app → src}/styles/dante/_popover.scss +0 -0
- data/{app → src}/styles/dante/_post.scss +0 -0
- data/{app → src}/styles/dante/_scaffold.scss +0 -0
- data/{app → src}/styles/dante/_tooltip.scss +0 -0
- data/{app → src}/styles/dante/_utilities.scss +0 -0
- data/{app → src}/styles/dante/_variables.scss +0 -0
- data/{app → src}/styles/dante/blame.scss +0 -0
- data/{app → src}/styles/dante.scss +0 -0
- data/{app → src}/styles/draft.css +0 -0
- data/src/styles/fonts/dante/dante.eot +0 -0
- data/src/styles/fonts/dante/dante.svg +18 -0
- data/src/styles/fonts/dante/dante.ttf +0 -0
- data/src/styles/fonts/dante/dante.woff +0 -0
- data/src/styles/fonts/dante/fontello.eot +0 -0
- data/src/styles/fonts/dante/fontello.svg +36 -0
- data/src/styles/fonts/dante/fontello.ttf +0 -0
- data/src/styles/fonts/dante/fontello.woff +0 -0
- data/src/utils/find_entities.js +17 -0
- data/src/utils/html2content.js +127 -0
- data/src/utils/save_content.js +80 -0
- data/{app → src}/utils/selection.js +0 -0
- data/tools/.eslintrc +9 -0
- data/tools/amd/README.md +7 -0
- data/tools/amd/bower.json +19 -0
- data/tools/amd/build.js +36 -0
- data/tools/build-cli.js +46 -0
- data/tools/build.js +30 -0
- data/tools/buildBabel.js +32 -0
- data/tools/constants.js +10 -0
- data/tools/dist/build.js +13 -0
- data/tools/docs/build.js +12 -0
- data/tools/es/build.js +27 -0
- data/tools/exec.js +50 -0
- data/tools/fs-utils.js +35 -0
- data/tools/lib/build.js +14 -0
- data/tools/promisify.js +14 -0
- data/webpack/base.config.js +89 -0
- data/webpack/docs.config.js +147 -0
- data/webpack/webpack.config.js +78 -0
- data/webpack.config-doc.js +5 -0
- data/webpack.config.js +3 -147
- data/yarn.lock +973 -718
- metadata +108 -64
- data/app/components/App.cjsx +0 -1083
- data/app/components/blocks/embed.cjsx +0 -109
- data/app/components/blocks/image.cjsx +0 -316
- data/app/components/blocks/placeholder.cjsx +0 -60
- data/app/components/blocks/video.cjsx +0 -75
- data/app/components/debug.cjsx +0 -96
- data/app/components/decorators/link.cjsx +0 -61
- data/app/components/popovers/addButton.cjsx +0 -247
- data/app/components/popovers/image.cjsx +0 -160
- data/app/components/popovers/link.cjsx +0 -87
- data/app/components/popovers/toolTip.cjsx +0 -326
- data/app/data/poc.js +0 -15
- data/app/demo.js +0 -7
- data/app/initialize.js +0 -4
- data/app/utils/find_entities.coffee +0 -20
- data/app/utils/html2content.coffee +0 -120
- data/app/utils/save_content.coffee +0 -63
- data/lib/dante2-editor/rails.rb +0 -16
@@ -0,0 +1,377 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import ReactDOM from 'react-dom'
|
3
|
+
|
4
|
+
import {
|
5
|
+
Entity,
|
6
|
+
RichUtils,
|
7
|
+
AtomicBlockUtils,
|
8
|
+
EditorBlock,
|
9
|
+
EditorState } from 'draft-js'
|
10
|
+
|
11
|
+
import axios from "axios"
|
12
|
+
|
13
|
+
import { updateDataOfBlock } from '../../model/index.js'
|
14
|
+
|
15
|
+
export default class ImageBlock extends React.Component {
|
16
|
+
|
17
|
+
constructor(props) {
|
18
|
+
super(props)
|
19
|
+
|
20
|
+
this.blockPropsSrc = this.blockPropsSrc.bind(this)
|
21
|
+
this.defaultUrl = this.defaultUrl.bind(this)
|
22
|
+
this.defaultAspectRatio = this.defaultAspectRatio.bind(this)
|
23
|
+
this.updateData = this.updateData.bind(this)
|
24
|
+
this.replaceImg = this.replaceImg.bind(this)
|
25
|
+
this.startLoader = this.startLoader.bind(this)
|
26
|
+
this.stopLoader = this.stopLoader.bind(this)
|
27
|
+
this.handleUpload = this.handleUpload.bind(this)
|
28
|
+
this.aspectRatio = this.aspectRatio.bind(this)
|
29
|
+
this.updateDataSelection = this.updateDataSelection.bind(this)
|
30
|
+
this.handleGrafFigureSelectImg = this.handleGrafFigureSelectImg.bind(this)
|
31
|
+
this.getUploadUrl = this.getUploadUrl.bind(this)
|
32
|
+
this.uploadFile = this.uploadFile.bind(this)
|
33
|
+
this.uploadCompleted = this.uploadCompleted.bind(this)
|
34
|
+
this.updateProgressBar = this.updateProgressBar.bind(this)
|
35
|
+
this.placeHolderEnabled = this.placeHolderEnabled.bind(this)
|
36
|
+
this.placeholderText = this.placeholderText.bind(this)
|
37
|
+
this.handleFocus = this.handleFocus.bind(this)
|
38
|
+
this.render = this.render.bind(this)
|
39
|
+
let existing_data = this.props.block.getData().toJS()
|
40
|
+
|
41
|
+
this.config = this.props.blockProps.config
|
42
|
+
this.file = this.props.blockProps.data.get('file')
|
43
|
+
this.state = {
|
44
|
+
loading: false,
|
45
|
+
selected: false,
|
46
|
+
loading_progress: 0,
|
47
|
+
enabled: false,
|
48
|
+
caption: this.defaultPlaceholder(),
|
49
|
+
direction: existing_data.direction || "center",
|
50
|
+
width: 0,
|
51
|
+
height: 0,
|
52
|
+
file: null,
|
53
|
+
url: this.blockPropsSrc() || this.defaultUrl(existing_data),
|
54
|
+
aspect_ratio: this.defaultAspectRatio(existing_data)
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
blockPropsSrc() {
|
59
|
+
// console.log @.props.blockProps.data.src
|
60
|
+
return this.props.blockProps.data.src
|
61
|
+
}
|
62
|
+
/*
|
63
|
+
debugger
|
64
|
+
block = @.props
|
65
|
+
entity = block.block.getEntityAt(0)
|
66
|
+
if entity
|
67
|
+
data = Entity.get(entity).getData().src
|
68
|
+
else
|
69
|
+
null
|
70
|
+
*/
|
71
|
+
|
72
|
+
defaultUrl(data) {
|
73
|
+
if (data.url) {
|
74
|
+
return data.url
|
75
|
+
}
|
76
|
+
|
77
|
+
if (data.url) {
|
78
|
+
if (data.file) {
|
79
|
+
return URL.createObjectURL(data.file)
|
80
|
+
} else {
|
81
|
+
return data.url
|
82
|
+
}
|
83
|
+
} else {
|
84
|
+
return this.props.blockProps.data.src
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
defaultPlaceholder() {
|
89
|
+
return this.props.blockProps.config.image_caption_placeholder
|
90
|
+
}
|
91
|
+
|
92
|
+
defaultAspectRatio(data) {
|
93
|
+
if (data.aspect_ratio) {
|
94
|
+
return {
|
95
|
+
width: data.aspect_ratio['width'],
|
96
|
+
height: data.aspect_ratio['height'],
|
97
|
+
ratio: data.aspect_ratio['ratio']
|
98
|
+
}
|
99
|
+
} else {
|
100
|
+
return {
|
101
|
+
width: 0,
|
102
|
+
height: 0,
|
103
|
+
ratio: 100
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
getAspectRatio(w, h) {
|
109
|
+
let maxWidth = 1000
|
110
|
+
let maxHeight = 1000
|
111
|
+
let ratio = 0
|
112
|
+
let width = w // Current image width
|
113
|
+
let height = h // Current image height
|
114
|
+
|
115
|
+
// Check if the current width is larger than the max
|
116
|
+
if (width > maxWidth) {
|
117
|
+
ratio = maxWidth / width // get ratio for scaling image
|
118
|
+
height = height * ratio // Reset height to match scaled image
|
119
|
+
width = width * ratio // Reset width to match scaled image
|
120
|
+
|
121
|
+
// Check if current height is larger than max
|
122
|
+
} else if (height > maxHeight) {
|
123
|
+
ratio = maxHeight / height // get ratio for scaling image
|
124
|
+
width = width * ratio // Reset width to match scaled image
|
125
|
+
height = height * ratio // Reset height to match scaled image
|
126
|
+
}
|
127
|
+
|
128
|
+
let fill_ratio = height / width * 100
|
129
|
+
let result = { width, height, ratio: fill_ratio }
|
130
|
+
// console.log result
|
131
|
+
return result
|
132
|
+
}
|
133
|
+
|
134
|
+
// will update block state
|
135
|
+
updateData() {
|
136
|
+
let { blockProps } = this.props
|
137
|
+
let { block } = this.props
|
138
|
+
let { getEditorState } = this.props.blockProps
|
139
|
+
let { setEditorState } = this.props.blockProps
|
140
|
+
let data = block.getData()
|
141
|
+
let newData = data.merge(this.state).merge({ forceUpload: false })
|
142
|
+
return setEditorState(updateDataOfBlock(getEditorState(), block, newData))
|
143
|
+
}
|
144
|
+
|
145
|
+
replaceImg() {
|
146
|
+
this.img = new Image()
|
147
|
+
this.img.src = this.refs.image_tag.src
|
148
|
+
this.setState({
|
149
|
+
url: this.img.src })
|
150
|
+
let self = this
|
151
|
+
// exit only when not blob and not forceUload
|
152
|
+
if (!this.img.src.includes("blob:") && !this.props.block.data.get("forceUpload")) {
|
153
|
+
return
|
154
|
+
}
|
155
|
+
return this.img.onload = () => {
|
156
|
+
this.setState({
|
157
|
+
width: this.img.width,
|
158
|
+
height: this.img.height,
|
159
|
+
aspect_ratio: self.getAspectRatio(this.img.width, this.img.height)
|
160
|
+
})
|
161
|
+
|
162
|
+
return this.handleUpload()
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
startLoader() {
|
167
|
+
return this.setState({
|
168
|
+
loading: true })
|
169
|
+
}
|
170
|
+
|
171
|
+
stopLoader() {
|
172
|
+
return this.setState({
|
173
|
+
loading: false })
|
174
|
+
}
|
175
|
+
|
176
|
+
handleUpload() {
|
177
|
+
this.startLoader()
|
178
|
+
this.props.blockProps.addLock()
|
179
|
+
this.updateData()
|
180
|
+
return this.uploadFile()
|
181
|
+
}
|
182
|
+
|
183
|
+
componentDidMount() {
|
184
|
+
return this.replaceImg()
|
185
|
+
}
|
186
|
+
|
187
|
+
aspectRatio() {
|
188
|
+
return {
|
189
|
+
maxWidth: `${ this.state.aspect_ratio.width }`,
|
190
|
+
maxHeight: `${ this.state.aspect_ratio.height }`,
|
191
|
+
ratio: `${ this.state.aspect_ratio.height }`
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
updateDataSelection() {
|
196
|
+
const { getEditorState, setEditorState } = this.props.blockProps
|
197
|
+
const newselection = getEditorState().getSelection().merge({
|
198
|
+
anchorKey: this.props.block.getKey(),
|
199
|
+
focusKey: this.props.block.getKey()
|
200
|
+
})
|
201
|
+
|
202
|
+
return setEditorState(EditorState.forceSelection(getEditorState(), newselection))
|
203
|
+
}
|
204
|
+
|
205
|
+
handleGrafFigureSelectImg(e) {
|
206
|
+
e.preventDefault()
|
207
|
+
return this.setState({ selected: true }, this.updateDataSelection)
|
208
|
+
}
|
209
|
+
|
210
|
+
//main_editor.onChange(main_editor.state.editorState)
|
211
|
+
|
212
|
+
coords() {
|
213
|
+
return {
|
214
|
+
maxWidth: `${ this.state.aspect_ratio.width }px`,
|
215
|
+
maxHeight: `${ this.state.aspect_ratio.height }px`
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
getBase64Image(img) {
|
220
|
+
let canvas = document.createElement("canvas")
|
221
|
+
canvas.width = img.width
|
222
|
+
canvas.height = img.height
|
223
|
+
let ctx = canvas.getContext("2d")
|
224
|
+
ctx.drawImage(img, 0, 0)
|
225
|
+
let dataURL = canvas.toDataURL("image/png")
|
226
|
+
|
227
|
+
return dataURL
|
228
|
+
}
|
229
|
+
|
230
|
+
formatData() {
|
231
|
+
let formData = new FormData()
|
232
|
+
if (this.file) {
|
233
|
+
let formName = this.config.upload_formName || 'file'
|
234
|
+
|
235
|
+
formData.append(formName, this.file)
|
236
|
+
return formData
|
237
|
+
} else {
|
238
|
+
formData.append('url', this.props.blockProps.data.get("url"))
|
239
|
+
return formData
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
getUploadUrl() {
|
244
|
+
let url = this.config.upload_url
|
245
|
+
if (typeof url === "function") {
|
246
|
+
return url()
|
247
|
+
} else {
|
248
|
+
return url
|
249
|
+
}
|
250
|
+
}
|
251
|
+
|
252
|
+
getUploadHeaders() {
|
253
|
+
return this.config.upload_headers || {}
|
254
|
+
}
|
255
|
+
|
256
|
+
uploadFile() {
|
257
|
+
let handleUp
|
258
|
+
axios({
|
259
|
+
method: 'post',
|
260
|
+
url: this.getUploadUrl(),
|
261
|
+
headers: this.getUploadHeaders(),
|
262
|
+
data: this.formatData(),
|
263
|
+
onUploadProgress: e => {
|
264
|
+
return this.updateProgressBar(e)
|
265
|
+
}
|
266
|
+
}).then(result => {
|
267
|
+
this.uploadCompleted(result.data)
|
268
|
+
this.props.blockProps.removeLock()
|
269
|
+
this.stopLoader()
|
270
|
+
this.file = null
|
271
|
+
|
272
|
+
if (this.config.upload_callback) {
|
273
|
+
return this.config.upload_callback(result, this)
|
274
|
+
}
|
275
|
+
}).catch(error => {
|
276
|
+
this.props.blockProps.removeLock()
|
277
|
+
this.stopLoader()
|
278
|
+
|
279
|
+
console.log(`ERROR: got error uploading file ${ error }`)
|
280
|
+
if (this.config.upload_error_callback) {
|
281
|
+
return this.config.upload_error_callback(error, this)
|
282
|
+
}
|
283
|
+
})
|
284
|
+
|
285
|
+
return handleUp = json_response => {
|
286
|
+
return this.uploadCompleted(json_response, n)
|
287
|
+
}
|
288
|
+
}
|
289
|
+
|
290
|
+
uploadCompleted(json) {
|
291
|
+
return this.setState({ url: json.url }, this.updateData)
|
292
|
+
}
|
293
|
+
|
294
|
+
updateProgressBar(e) {
|
295
|
+
let complete = this.state.loading_progress
|
296
|
+
if (e.lengthComputable) {
|
297
|
+
complete = e.loaded / e.total * 100
|
298
|
+
complete = complete != null ? complete : { complete: 0 }
|
299
|
+
this.setState({
|
300
|
+
loading_progress: complete })
|
301
|
+
return console.log(`complete: ${ complete }`)
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
placeHolderEnabled() {
|
306
|
+
return this.state.enabled || this.props.block.getText()
|
307
|
+
}
|
308
|
+
|
309
|
+
placeholderText() {
|
310
|
+
if (this.placeHolderEnabled()) {
|
311
|
+
return ""
|
312
|
+
}
|
313
|
+
return "Write caption for image (optional)"
|
314
|
+
}
|
315
|
+
|
316
|
+
handleFocus(e) {
|
317
|
+
// console.log "focus on placeholder"
|
318
|
+
return setTimeout(() => {
|
319
|
+
return this.setState({
|
320
|
+
enabled: true })
|
321
|
+
}, 0)
|
322
|
+
}
|
323
|
+
|
324
|
+
render() {
|
325
|
+
|
326
|
+
return (
|
327
|
+
<div ref="image_tag2" suppressContentEditableWarning={true}>
|
328
|
+
<div className="aspectRatioPlaceholder is-locked"
|
329
|
+
style={this.coords()}
|
330
|
+
onClick={this.handleGrafFigureSelectImg}>
|
331
|
+
<div style={{ paddingBottom: `${ this.state.aspect_ratio.ratio }%` }}
|
332
|
+
className='aspect-ratio-fill' />
|
333
|
+
<img src={this.state.url}
|
334
|
+
ref="image_tag"
|
335
|
+
height={this.state.aspect_ratio.height}
|
336
|
+
width={this.state.aspect_ratio.width}
|
337
|
+
className='graf-image' />
|
338
|
+
<Loader toggle={this.state.loading}
|
339
|
+
progress={this.state.loading_progress} />
|
340
|
+
</div>
|
341
|
+
<figcaption className='imageCaption' onMouseDown={this.handleFocus}>
|
342
|
+
{ !this.state.enabled ?
|
343
|
+
<span className="danteDefaultPlaceholder">
|
344
|
+
{this.placeholderText()}
|
345
|
+
</span> : undefined}
|
346
|
+
<EditorBlock {...Object.assign({}, this.props, {
|
347
|
+
"editable": true, "className": "imageCaption" })
|
348
|
+
} />
|
349
|
+
</figcaption>
|
350
|
+
</div>
|
351
|
+
)
|
352
|
+
}
|
353
|
+
}
|
354
|
+
|
355
|
+
class Loader extends React.Component {
|
356
|
+
|
357
|
+
render() {
|
358
|
+
return (
|
359
|
+
<div>
|
360
|
+
{ this.props.toggle
|
361
|
+
? <div className="image-upoader-loader">
|
362
|
+
<p>
|
363
|
+
{ this.props.progress === 100
|
364
|
+
? "processing image..."
|
365
|
+
: <span>
|
366
|
+
<span>loading</span> { Math.round( this.props.progress ) }
|
367
|
+
</span>
|
368
|
+
}
|
369
|
+
</p>
|
370
|
+
</div>
|
371
|
+
: undefined
|
372
|
+
}
|
373
|
+
</div>
|
374
|
+
)
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
import React from 'react'
|
3
|
+
import ReactDOM from 'react-dom'
|
4
|
+
|
5
|
+
import { Entity, RichUtils, AtomicBlockUtils, EditorBlock } from 'draft-js'
|
6
|
+
|
7
|
+
export default class PlaceholderBlock extends React.Component {
|
8
|
+
constructor(props) {
|
9
|
+
super(props)
|
10
|
+
this.placeholderText = this.placeholderText.bind(this)
|
11
|
+
this.placeholderFromProps = this.placeholderFromProps.bind(this)
|
12
|
+
this.defaultText = this.defaultText.bind(this)
|
13
|
+
this.handleFocus = this.handleFocus.bind(this)
|
14
|
+
this.classForDefault = this.classForDefault.bind(this)
|
15
|
+
this.state = {
|
16
|
+
enabled: false,
|
17
|
+
data: this.props.blockProps.data.toJS()
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
placeholderText() {
|
22
|
+
if (this.state.enabled) {
|
23
|
+
return ""
|
24
|
+
}
|
25
|
+
return this.props.blockProps.data.toJS().placeholder || this.placeholderFromProps() || this.defaultText()
|
26
|
+
}
|
27
|
+
//if @.props.blockProps.data then @.props.blockProps.data.placeholder else @defaultText()
|
28
|
+
|
29
|
+
|
30
|
+
placeholderFromProps() {
|
31
|
+
return this.props.block.toJS().placeholder
|
32
|
+
}
|
33
|
+
|
34
|
+
defaultText() {
|
35
|
+
return "write something "
|
36
|
+
}
|
37
|
+
|
38
|
+
componentDidMount() {}
|
39
|
+
|
40
|
+
handleFocus(e) {
|
41
|
+
// console.log "focus on placeholder"
|
42
|
+
return setTimeout(() => {
|
43
|
+
return this.setState({
|
44
|
+
enabled: true })
|
45
|
+
}, 0)
|
46
|
+
}
|
47
|
+
|
48
|
+
classForDefault() {
|
49
|
+
if (!this.state.enabled) {
|
50
|
+
return "defaultValue defaultValue--root"
|
51
|
+
} else {
|
52
|
+
return ""
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
render() {
|
57
|
+
return (
|
58
|
+
<span className={this.classForDefault()} onMouseDown={this.handleFocus}>
|
59
|
+
{this.placeholderText()}
|
60
|
+
<EditorBlock {...Object.assign({}, this.props, {
|
61
|
+
"className": "imageCaption",
|
62
|
+
"placeholder": "escrive alalal"
|
63
|
+
})} />
|
64
|
+
</span>
|
65
|
+
)
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
import React from 'react'
|
3
|
+
import ReactDOM from 'react-dom'
|
4
|
+
|
5
|
+
import { Entity, RichUtils, AtomicBlockUtils, EditorBlock } from 'draft-js'
|
6
|
+
|
7
|
+
import { updateDataOfBlock } from '../../model/index.js'
|
8
|
+
|
9
|
+
import axios from "axios"
|
10
|
+
|
11
|
+
export default class VideoBlock extends React.Component {
|
12
|
+
constructor(props) {
|
13
|
+
super(props)
|
14
|
+
//api_key = "86c28a410a104c8bb58848733c82f840"
|
15
|
+
|
16
|
+
this.updateData = this.updateData.bind(this)
|
17
|
+
this.dataForUpdate = this.dataForUpdate.bind(this)
|
18
|
+
this.state = { embed_data: this.defaultData() }
|
19
|
+
}
|
20
|
+
|
21
|
+
defaultData() {
|
22
|
+
let existing_data = this.props.block.getData().toJS()
|
23
|
+
return existing_data.embed_data || {}
|
24
|
+
}
|
25
|
+
|
26
|
+
// will update block state
|
27
|
+
updateData() {
|
28
|
+
const { block, blockProps } = this.props
|
29
|
+
const { getEditorState, setEditorState } = this.props.blockProps
|
30
|
+
const data = block.getData()
|
31
|
+
const newData = data.merge(this.state)
|
32
|
+
return setEditorState(updateDataOfBlock(getEditorState(), block, newData))
|
33
|
+
}
|
34
|
+
|
35
|
+
dataForUpdate() {
|
36
|
+
return this.props.blockProps.data.toJS()
|
37
|
+
}
|
38
|
+
|
39
|
+
componentDidMount() {
|
40
|
+
|
41
|
+
if (!this.props.blockProps.data) {
|
42
|
+
return
|
43
|
+
}
|
44
|
+
// ensure data isnt already loaded
|
45
|
+
if (!this.dataForUpdate().endpoint && !this.dataForUpdate().provisory_text) {
|
46
|
+
return
|
47
|
+
}
|
48
|
+
|
49
|
+
return axios({
|
50
|
+
method: 'get',
|
51
|
+
url: `${ this.dataForUpdate().endpoint }${ this.dataForUpdate().provisory_text }&scheme=https`
|
52
|
+
}).then(result => {
|
53
|
+
return this.setState({ embed_data: result.data } //JSON.parse(data.responseText)
|
54
|
+
, this.updateData)
|
55
|
+
}).catch(error => {
|
56
|
+
return console.log("TODO: error")
|
57
|
+
})
|
58
|
+
}
|
59
|
+
|
60
|
+
classForImage() {
|
61
|
+
if (this.state.embed_data.thumbnail_url) {
|
62
|
+
return ""
|
63
|
+
} else {
|
64
|
+
return "mixtapeImage--empty u-ignoreBlock"
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
render() {
|
69
|
+
return (
|
70
|
+
<figure className='graf--figure graf--iframe graf--first' tabIndex='0'>
|
71
|
+
<div className='iframeContainer'
|
72
|
+
dangerouslySetInnerHTML={ { __html: this.state.embed_data.html } } />
|
73
|
+
<figcaption className='imageCaption'>
|
74
|
+
<EditorBlock {...Object.assign({}, this.props, { "className": "imageCaption" })} />
|
75
|
+
</figcaption>
|
76
|
+
</figure>
|
77
|
+
)
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|