Here is (5 years later I know) a graphical explanation of what why this happens. This is, in fact, what @osma describes but graphically explained:
When you bold a string in GDocs you are wrapping the string into a container, presumably <strong></strong>
but they may use any other syntax. For simplicity lets just say that bold'ing a string just requires a "+" at the beginning of the word. So that, for simplicity, the text "lorem ipsum" would become lorem +ipsum
and not lorem <strong>ipsum<strong>
1
Both Alice and Bob start with the text "Lorem ipsum"
2
Bob then deletes "ipsum". Notice that he sends the changeset retain(6), delete(5)
to the server. A changeset is essentially a patch, Google probably used this library.
3
Now Alice bolds "ipsum" (adding "+"). She sends is the changeset retain(6), insert(+), retain(5)
4
Both changesets are traveling to the server. The server knows nothing about these sets yet.
5
Assuming the worst scenario: Bob's package arrives first and then the word will be deleted. The other scenario is obvious.
6
When Alice's package arrives, it will only add a "+" to the text because what she sent is only a single changeset.
7
Both texts are then broadcasted to the clients. This is the first one.
8
And this is the second one.
9
After patching these changesets into the original text you end up with "Lorem +". The server and all clients now have the same text. The +
symbol would later be erased by an common HTML clean process which eliminates empty tags like <tag></tag>
,
To test this demo go to: http://operational-transformation.github.io/visualization.html. There you can play with the texts and packages as they are sent/received.