For those who haven't worked with the Google Docs editor here's a short explanation of how it works:
With that out of the way, here's my request:
I'm working on a plugin that interacts with the Google Doc and I need to be able to do two things:
I've been exhausting a lot of ideas about just how to handle this, but so far I've only manage to get a buggy solution for the latter problem (I perform a backspace, determine where the text changed and undo the backspace).
I'm looking for all the best ideas you can come up with to solve these problems. They don't need to be cross browser, but they do need to be able to be turned into something robust that will also handle things such as font size changed mid line.
A little bit of extra info explaining what a Google Doc looks like in HTML:
<wrapper> // Simplified wrapper containing margins, pagination and similar
<div class="kix-paragraphrenderer"> // single DIV per page wrapping all content
// Multiple paragraphs separated by linebreak created by Enter key:
<div class="kix-paragraphrendeder">...</div>
<div class="kix-paragraphrendeder">...</div>
<div class="kix-paragraphrendeder">
// Multiple wrapper divs created by Google's word wrapping:
<div class="kix-lineview">...</div>
<div class="kix-lineview">...</div>
<div class="kix-lineview">
// Single inner wrapper, still full width of first wrapper paragraph:
<div class="kix-lineview-content">
// Single wrapper SPAN containing full text of the line, but not display:block
<span class="kix-lineview-text-block">
// Multiple spans, one per new font change such as normal/bold text,
// change in font size, indentation and similar:
<span>This is normal text</span>
<span style="font-size:40px; padding-left:4px;">This larger text.</span>
<span style="font-weight:bold; padding-left:10px;">This is bold text</span>
<span style="padding-left:4px;">More normal text</span>
</span>
</div>
</div>
</div>
</div>
</wrapper>
After more tinkering I came to the conclusion that it is extremely troublesome - if not impossible - to try and programmatically determine cursor position with regard to a letter inside a <span>
, simply because the <span>
is the smallest element that is measurable (correct me if I am wrong).
So how to solve the problem? Here's what I ended up doing:
<div>
<div class="kix-paragraphrenderer">
) - I could get the entire text, but wanted to limit the computational load.<div class="kix-lineview">
)<div class="kix-lineview-content">
)<span class="kix-lineview-text-block">
)<span>
's of the text blockinnerText
of the <span>
<div>
with the currently applied style extracted from style.cssText
of the current <span>
<div>
and save this in an array. I now have a position of each single character.This is obviously a bit simplied (I left out details about margins and paddings of the different elements), but it covers the idea behind how it's possible to get the cursor position.
It works quite well, but there are many pitfalls and a lot of measuring required. On top of that it's also required to post-parse the text if you want to use it for anything, since tabs, spaces and linebreaks aren't always included in innerText
(depending on where these are in the text, Google may or may not make them through positioning of new elements).
I made something like Kix two years ago Google Docs. And for any HTML design and yes, for IE6 too:-) How? All we need is to compute letter absolute position. How? Replace textNode with inline element without layout, that's important, and then use Element.getClientRects I remember I also needed wrap just letter and compute its position via fast and reliable https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
The trick how to detect lines and wraps for home and end keys was based on some vertical heuristic letter position change. Something like if base line is different, than stop caret walking. It was pretty fast and with any markup and without any caching. Holy grail:)
The only not resolvable problem was justified text, because letters were distributed randomly and spaces between them was not computable.
That project is dead http://webeena.com now. Bad management killed it (and me almost too).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.