[Patch] quite complete caret navigation

Leo Savernik l.savernik at aon.at
Mon Aug 18 23:00:18 BST 2003


Caret Navigation
=============================

Caret navigation is quite complete now in terms of what the user expects. A 
fat explanation for a fat patch.


Overview
-----------------------------

The patch provides the following functionality:
- Activating the caret/updating the caret on relayout
- Keyboard Navigation. All common keys should work as expected, also in 
combination with shift to select text.
- Placing the caret by mouse.

There's still no means to activate caret mode by GUI, but I think I'll add an 
action soon so that independent people can test it.

All caret related changes are encapsuled in
#ifndef KHTML_NO_CARET
#endif
blocks. Defining this will simply not compile caret mode in (however, I 
haven't yet tested it).


Detailed Changes
-----------------------------

A detailed explanation of the changes follows:
In khtml_part:
- new property editable. Toggles whole document editable (when it's 
implemented)
- new property caretMode. Toggles caret mode.
- new signal caretPositionChanged.
- Matt Newell's optimization patch for node order determination
- trivia: replaced replace(QRegExp, QString) by replace(QChar, QChar), fixed 
typos

In khtmlview:
- main part of caret navigation logic. See architecture.

In testkhtml:
- Added two buttons to toggle editable, caret Mode.

In css/:
- Added new property -konq-user-input: [ enable | disable | none ]

In dom/dom_doc:
- Added property designMode. Functionally equivalent to KHTMLPart::editable.

In dom/dom_element:
- Added property contentEditable. It's a shortcut for inquiring this element's 
-konq-user-input value

In dom/dom_node:
- getCursor is deprecated without replacement (If anybody needs this, please 
yell).

In html/:
- changed maximum length of attribute names from 14 to 20 (contenteditable is 
15, and it took me quite a long time to find out why khtml hadn't recognized 
it)
 
In rendering/Makefile.am:
- activated compilation of render_line.cpp

In rendering/bidi:
- merged the Inline*Box changes from Safari in the least intrusive way.

In rendering/font:
- added comments
- added getters for letter spacing and word spacing

In rendering/render_box:
- updated position method
- added caretPos method

In rendering/render_br:
- simplified caretPos implementation (will vanish in a later rev.)

In rendering/render_flow:
- ported over API for line traversal from Safari.
- added special caretPos method.

In rendering/render_image:
- added caretPos method (will vanish in a later rev.)

In rendering/render_line:
- ported from Safari, made compilable.
- added InlineBox::minOffset, InlineBox::maxOffset
- const'ed methods that obviously should be const but weren't

In rendering/render_object:
- ported from Safari: createInlineBox, modified position
- renamed cursorPos to caretPos, and extended parameters
- new methods minOffset, maxOffset

In rendering/render_style:
- added inheritable property EUserInput, accessor RenderStyle::userInput

In rendering/render_text:
- derived TextSlave from InlineBox, and renamed it to InlineTextBox
- made InlineTextBox::checkSelectionPoint correctly handle justified text
- added InlineTextBox::offsetForPoint, finds approximate offset to given 
x-coordinate
- added method InlineTextBox::width, which also treats justified text 
correctly.
- renamed findTextSlave to findInlineTextBox and fixed it for rare cases when 
it would find the wrong text box.
- renamed deleteTextSlaves to deleteTextBoxes

In xml/:
- implementations of the changes in dom/
- NodeImpl: added prevLeafNode, nextLeafNode, minOffset, maxOffset


Architecture
-----------------------------

For navigation purposes, the whole document is treated as a linear list of 
lines. Each line itself is composed of one to many inline boxes containing 
the actual characters/objects.

As SGML-documents are represented by trees, the line representation is created 
ad hoc by the aid of several classes.

LinearDocument:
Represents the whole document as a linear list of lines. It has iterators to 
the first line, last line, beginning (before first line), and end (beyond 
last line) documents and tries to somewhat resemble STL semantics.

LineIterator:
Iterates through the lines of a LinearDocument object.

EditableLineIterator:
As not every line is necessarily editable, this iterator only delivers those 
lines which are deemed to be editable/navigable. Works otherwise just like 
LineIterator and is comparable to it.

InlineBoxIterator:
Iterates through the inline boxes of a line.

EditableInlineBoxIterator:
Analogically to EditableLineIterator, this iterator only regards those boxes 
that are editable/navigable.

EditableCharacterIterator:
This iterator iterates through all leaf-node characters of the document, 
effectively treating it as a linear stream. Non-character elements are 
treated as whitespaces.

Btw, these classes are *private*. And it will stay that way. I have yet to 
come up with a sensible persistent public API for customizing navigation, but 
that's far into the future. The explanations are here for the people who 
review the patch (which will be as many as for my last patch, that is: zero 
;-) ).


Known Bugs
-----------------------------

Though the suck factor of navigation has become very low, there are still the 
following known bugs (to the hundreds of not yet known):
- caret placement by mouse doesn't work reliably.
- movement through tables doesn't work as expected.
- movement through invisible elements is possible (that looks so stupid, you 
can't imagine)
- when caret mode is initially activated, the caret does sometimes not move on 
the first keypress.


Regressions
-----------------------------

None that I know of.
During the development I had some crashes in the new code, but I think I 
sorted them all out. There were *no* crashes in the old code ever, so 
everything not relying on navigation should continue working reliably.


Missing Features
-----------------------------

- Editing capabilities.
- Drag & drop.


Fixed Bug
-----------------------------

In the course of implementation I had to fix some bugs which were tolerable 
for a read-only browser, but are inacceptable for caret navigation:

#46224 and dupes (but not #50683, must be investigated separately): x-range 
mismatches with justified text


I'll commit these changes soon, this time really, I promise.

See patch:
http://bugs.kde.org/attachment.cgi?id=2269&action=view





More information about the kfm-devel mailing list