-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Try block annotation, starting with full block annotation #3628
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3628 +/- ##
=========================================
- Coverage 36.95% 36.9% -0.05%
=========================================
Files 268 268
Lines 6673 6690 +17
Branches 1202 1203 +1
=========================================
+ Hits 2466 2469 +3
- Misses 3555 3569 +14
Partials 652 652
Continue to review full report at Codecov.
|
Some initial thoughts coming into this mostly uninitiated, not yet having looked at the implementation:
|
I would like to echo @aduth 's question about rich content:
Using an index counter for position in a tree can cause a lot of problems. You will need to consistently convert between the tree and the flat data. HTML data is inherently tree-based because formatting elements can be nested. This kind of counter can work in situations where you are guaranteed to have only plain text. Conversions can be simple if you are only allowing text and formatting elements. However, as soon as you have things which can't be represented as
Now, the textContent for this is just
If you get given position, 4 in this, that is obviously "hell|o". However, if you get given position 7, then that is probably "hello w|orld". But you can't just use offsets on the root container (or its only child) to work that out. You need to actually walk through the DOM, and identify which node that offset belongs to. As you walk, you need to accumulate how many index positions you've already walked, so you know when you reach your destination. This becomes much harder when you have levels of nesting with whitespace and non-breaking spaces and zero-width cursors. Then throw in all the random HTML content that can be added by plugins, hookins, metaboxes etc, and suddenly you need to ensure that you are supporting all of these elements in your HTML model. It is certainly manageable, but don't necessarily think that it's going to be easier than finding a tree-based alternative. |
@aduth Some thoughts after discussing this at WordCamp US.
After thinking about this more I think it makes more sense to have an array of blocks.
There should be a way to specify if an annotation is on a block or in the block. I don't want to make this implicit, so that is where
Given that, I will focus this PR completely on creating a block annotation API. Annotating inside blocks will be an iteration in the future. The
I brainstormed with @omarreiss on this and we came to the conclusion that as a user you always want to know where an annotation comes from. So that is why we connect these two concepts so clearly.
No, the date is probably the date of saving. So this field could be empty.
Probably later. I would say we start without rich content. We can always add this later. Position based annotation@ephox-mogran The reason I chose positions is that those are always very easy to reason about. I don't think we allow This also relates to #771, cc @iseulde. If all formatting on a paragraph block would be applied base on its position implementing annotations would be trivial. It is just another form of formatting. @ephox-mogran Can you tell me how a node based alternative would look like? My intuition is that that would require a lot of keeping track of changes to nodes. |
@ephox-mogran writes...
I am in agreement with you on this. I'm currently researching the way others have approached this in other platforms. A tree-based approach seems more robust to me at the moment. Having said that, there's another hairy thing to deal with. Something I've not had prior experience with is holding a selection to an editable chunk of content. Imagine that a user selects some text and annotates that selection, which is then highlighted. Later, another user comes along and fixes a typo, thereby altering the selection start/end offsets. On the surface, this looks tricky to deal with. Obviously it can be done though, because Pages on macOS supports it nicely, as do other platforms I've tested recently. It's a nice touch. It seems to me that it requires:
|
Can this be closed in favor of #7718 ? |
I think so |
Description
This is a PR that explores how to do annotation on blocks. A lot of work has gone into exploration instead of actual code changes. But this is the PoC I have running locally, so I thought it would be good to share it.
How did I get here
I first started thinking about different annotation data formats. I started with the least amount of data:
After discussing this with @omarreiss we iterated on this and ended up with the following data structure:
start
andend
: We figured that an annotation always has a start and an end position. Blocks can either be fully annotated or the text inside blocks can be annotated. So an annotation starts at a block and a position. And an annotation ends at a block and a position.blockAnnotation
: An annotation can either be a full block annotation or a default text annotation. For non-text blocks, there might not be a distinction, but I could see that you might want to comment on one image in a gallery block.comments
: Comments are objects on their own. They probably have more fields thanbody
anddate
, but those are the bare minimum.type
might be something we want to add.persist
andid
: Some annotations should be persisted, some shouldn't. So theid
is only relevant when an annotation needs to be persisted. Annotations that haven't been persisted to the server can be detected because they have noid
yet.In this data model, a comment is always bound to an annotation. This is a trade-off that forces a user to always be specific about what a comment is about.
Challenges
There are a ton of challenges to be solved. Persisting annotations is one that comes to mind. Which I have commented on here: #3026 (comment).
Another one is handling moving blocks. I think this can be solved by handling moving of blocks in the annotations reducer and changing the annotations to still be correct.
How Has This Been Tested?
By running it in Chrome & Firefox
Screenshots (jpeg or gifs if applicable):
n.a. (It doesn't look good yet)
Types of changes
New feature (non-breaking change which adds functionality)
Checklist:
TODO:
See #2893 and #3026.