-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use editor3 internal clipboard to copy entities from open editors #2509
Conversation
tsconfig.json
Outdated
@@ -11,8 +11,8 @@ | |||
"target": "es5", | |||
"lib": [ | |||
"dom", | |||
"es2015" | |||
"es2017" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: I needed this to get Object.entries
recognized by typescript but I ended up dropping that code. I still think we'll need this in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tomaskikutis maybe you know, could this commit cause us any problem regarding typescript compilation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works for me
"lib": [
"dom",
"es2015",
"es2016"
]
I think you might need to still include es2015
and es2016
even if you have es2017
included.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tomaskikutis are you sure? That's weird, I would assume the es2017 standard includes both es2015 and es2016
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try and see, but I think it might not automatically include the features of previous editions of the spec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it is working right now just with es2017, the compiler doesn't complain about anything
0bbf8c6
to
8bbb853
Compare
function processPastedHtml(props, html) { | ||
const {onChange, editorState, editorFormat} = props; | ||
let pastedContent = getContentStateFromHtml(html); | ||
function insertContentInState(props: any, _pastedContent: ContentState) : DraftHandleValue { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of props, take the actual arguments you need: editorState, editorFormat, onChange
. This way function signature becomes cleaner and you can add type annotations without needing to add it for the entire object.
It also makes it easier to understand and refactor the code if you take fewer arguments. For example pasteContentFromOpenEditor
which calls this function(insertContentInState
) takes props as an argument, and while I'm looking at pasteContentFromOpenEditor
I'm thinking "why does it take all props as an argument? And then I see: oh, it passes the entire object to another function, it must require it then I think. In this case, it's only two levels, but when you keep doing it, you end up with 6 levels of passing the entire object when you only need a few params from it which obfuscates your intention and creates dependencies(on the entire object) which should not be there.
Then comes a time when you need to call that function and you have those 3 required values(editorState, editorFormat, onChange
), but not the entire object and you think: "I'll just create an empty object with these 3 values and it will work for that function". And then someone modifying the function thinks "I've got the entire object, I can start using another property" - and the errors start coming.
That's probably more context than required, but I saw these things happen in the code and it's quite simple to avoid it.
By the way, if you use props
outside a React component, specify what kind props is that. It's obvious while in a React component, but otherwise it looks like _this
as an argument which doesn't really mean anything outside of the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you're right. I didn't think about it as I didn't write insertContentInState
(just renamed it) but I'm working on it right now while I fix other types. Thanks
package.json
Outdated
@@ -28,6 +28,7 @@ | |||
], | |||
"main": "scripts/index.js", | |||
"dependencies": { | |||
"@types/draft-js": "^0.10.24", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might not cause any issues, but I'd lock the version.
@@ -25,7 +20,8 @@ function removeMediaFromHtml(htmlString) : string { | |||
return element.innerHTML; | |||
} | |||
|
|||
function pasteContentFromOpenEditor(props: any, html: string) : DraftHandleValue { | |||
function pasteContentFromOpenEditor( | |||
html: string, editorState: EditorState, onChange: Function, editorFormat: Array<string>) : DraftHandleValue { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's alright for now, but try avoiding the use of Function
type, since it's very generic. You can define
interface IEditor3props {
onChange(editorState: EditorState): void;
}
and then access onChange
like a object property, so you have the whole function signature, but don't need to typed it entirely.
function functionWhichTakesOnChangeAsAnArgument(onChange: IEditor3props['onChange']) {
// ...
}
@@ -34,15 +30,15 @@ function pasteContentFromOpenEditor(props: any, html: string) : DraftHandleValue | |||
if (internalClipboard) { | |||
const blocksArray = []; | |||
|
|||
internalClipboard.map((b) => blocksArray.push(b)); | |||
internalClipboard.forEach((b) => blocksArray.push(b)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why aren't you passing internalClipboard
to createFromBlockArray
and instead are making a shallow copy?
} | ||
} | ||
} | ||
|
||
return DraftHandleValue.NOT_HANDLED; | ||
return 'not-handled'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong with DraftHandleValue
?
@@ -6,6 +6,7 @@ import {getDraftSelectionForEntireContent} from './getDraftSelectionForEntireCon | |||
import {resizeDraftSelection} from './resizeDraftSelection'; | |||
import {clearInlineStyles} from './clearInlineStyles'; | |||
import {changeSuggestionsTypes, blockStylesDescription, paragraphSuggestionTypes} from '../highlightsConfig'; | |||
import _ from 'lodash'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import {onlyWhatYouNeed} from 'lodash'
, so we can have a smaller bundle size.
@@ -1,4 +1,6 @@ | |||
/* eslint-disable no-unused-vars */ // eslint complains about EditorChangeType not being used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use eslint-disable-next-line
to avoid having to re-enable rules.
// eslint-disable-next-line no-unused-vars
import {EditorChangeType} from 'draft-js';
import {SelectionState, Modifier, EditorState} from 'draft-js';
@@ -0,0 +1,19 @@ | |||
patch-package |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ioanpocol I added a new dependency: patch-package
. With it we can modify any package under node_modules and make a patch like this one to fix a bug without waiting for a PR to be merged. This will patch the module after an npm install
automatically
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
SDESK-2996
The problem was that tables could not be pasted between editors because draft-js doesn't handle very well pasting custom entities to another editor. This attempts to use the first editor content (via internal clipboard) and insert it directly into the second editor.
If you copy something from an editor with images/tables/etc, refresh the page, and then paste it to another editor this fix won't work as it has no reference to the other editor. I'm thinking of another way of handling this situation, like copying the actual contentState instead of the html but that can be messy and I think it's not possible right now in draft
*My first approach to this issue was handling all paste by our custom html parser. I did implement this and it worked for tables but images/media were kind of tricky so I went for the second fix.