[webkit-dev] Rich Text Editing Questions, Refactoring of Position Classes
darin at apple.com
Tue Apr 6 09:47:55 PDT 2010
On Apr 6, 2010, at 9:29 AM, Alexey Proskuryakov wrote:
> 05.04.2010, в 22:46, Maciej Stachowiak написал(а):
>>> The current implementation allows for (and operates on) positions such as [img, 0] - [img, 1] or [br,0] - [br, 1]. Is there a fundamental reason to keep such positions within the internal representation rather than normalize them to [parent-of-img, index-of-img(+1)] - round-tripping perhaps?
>> Having fake positions like that is not good. I don't think there is a good reason for it. But the assumption got deeply embedded into the code, and it will take some doing to remove. One step in that direction would be to phase out all use of Position.deprecatedEditingOffset() and Position.node().
> I think that one reason is performance - "index-of-img" can be costly. But I completely agree that we should try to get rid of these.
Let me elaborate on what Maciej and Alexey said.
If we have an <img> element, there are three valid DOM positions adjacent to it:
A: [ parent-of-<img>, child-offset-of-<img> ]: before the image
B: [ <img>, 0 ]: inside the image
C: [ parent-of-<img>, child-offset-of-<img> + 1 ]: after the image
WebKit’s HTML editing code also makes use of an invalid DOM position:
D: [ <img>, 1 ]: inside the image, but used to represent the position after the image
Using D is never a good idea because it’s not a valid DOM position, so we can’t use it to construct a DOM range object. Having positions like D in our code at all leads to complexity and confusion.
Using B to represent the position before the image is also unconventional; the position is clearly “inside the image element”, whatever that means. Given that, it seems that editing-related code that starts with a position such as B should quickly convert it to either A or C as appropriate.
But computing A or C given a pointer to an image element is costly because it involves walking the parent's child nodes. In a large, flat document the cost is proportional to the size of the document. The same goes if we start with A or C and want to find the image element just before or just after the position.
There are other issues when the document is being changed with positions extant. If we add a child element to the <img> element’s parent before the <img> element, both A and C end up pointing to a different place in the document, but B and D will still point where they did before. So if we convert editing code that currently uses a position like B to instead use a position like A, it’s easy to change behavior without realizing it.
Encapsulating some of this into a class is one of the goals of the Position object, but we haven’t made much progress on untangling the mess.
More information about the webkit-dev