So I've written a complete selection/range implementation, which
allows much more sophisticated Rich Text Editor operations.  You can
obtain and manipulate the cursor or current selected range - with
this, I was able to trivially create a proper "Link" functionality to
deal with existing links in the editor.  Inspired from the partial
solution in gwt-rocket, it uses a structural selection model like the
W3C spec, with emulation to make it work the same in cursed IE*.  And
except for wrappers around js calls, everything is written in Java to
allow full GWT optimization.

I really think this functionality should be part of the GWT library,
as I think it's the main missing core feature needed to implement full
RTE capabilities without having to go import external JS RTE
libraries.  I could always post it as a separate library like gwt-
rocket, but it's already fairly annoying the number of these little
libraries with random bits of functionality, which quickly become
unsupported or bloated.  Additionally, due to an IE bug it would be
best to have a getSelection/getRange method directly as part of the
RichTextArea widget.

But that's just me, do others think this is a really need-to-have for
GWT?  If others feel it'd be a good addition to GWT, I'd be willing to
spend the time to try to get it in, maybe starting with getting it in
the incubator.  And through that would love to see any critiques or
better ways to do any of it.


Here's the API, purely structural and doesn't include any of the
position-based methods that IE has:


// Current selection is based on a document/window, so there is a
browser
// global selection, and a selection for any iframe windows.
class Selection
{
    // Get the browser global selection
    static Selection getSelection();

    // Get selection associated with a particular window, ie an RTE
iframe
    static Selection getSelection(JavaScriptObject window);

    // Get a range containing current selection.  Changes to the range
do not
    // affect the selection, and vice versa
    Range getRange();

    // Set the selection to what is contained in the range.
Subsequent
    // changes to this range object will not affect the selection
    void setRange(Range range);

    void clear();
    Document getDocument()
}

// Represents a range in an html document, as a start and end text
node,
// and the offset in to them, ie between the two | marks here:
//
// <b>A r|ange <a>that spans</a></b><i> some elem|ents.</i>
class Range
{
    // Constructors
    Range(Document doc);
    Range(Element element);
    Range(RangeEndPoint cursorPoint);
    Range(RangeEndPoint startPoint, RangeEndPoint endPoint);

    // Get the start/end points of this range, or the cursor if no
selection
    RangeEndPoint getCursor();
    RangeEndPoint getStart();
    RangeEndPoint getEnd();

    // Get the document this range is contained within
    Document getDocument();

    // Set the range to be a cursor, ie start == end
    void setCursor(RangeEndPoint cursorPoint);

    // Set the range to surround the given element
    void setRange(Element element);

    // Set the endpoints of the range
    void setRange(RangeEndPoint startPoint, RangeEndPoint endPoint);

    // Set the start or end point of the range
    void setStartPoint(RangeEndPoint startPoint);
    void setEndPoint(RangeEndPoint endPoint);


    // Returns true if start == end
    boolean isCursor();

    // Collapses the range to a cursor, either to the start or end
point
    void collapse(boolean start);

    // Compare the start or end point of this range with the start or
end point
    // of another.  "how" determines which endpoints, ie
Range.START_TO_END
    int compareBoundaryPoint(Range compare, short how);

    // Get just the text selected, ie "ange that spans some elem"
    String getText();

    // Get the html selected, including any tags needed to make it
complete, ie:
    // "<b>ange <a>that spans</a></b><i> some elem<i>"
    String getHtmlText();

    // Returns the lowest level element that completely contains this
range
    Element getCommonAncestor();


    // Returns an ordered list of all the text nodes in this range
    List<Text> getSelectedTextNodes();

    // Copy the contents of this range into the given element, leaving
the
    // document undisturbed
    void copyContents(Element copyInto);

    // Delete the contents of this range from the document
    void deleteContents();

    // Extracts the contents of this range into the given element,
removing them
    // from the document
    void extractContents(Element copyInto);
    Element extractContents(); // same but creates a span element for
you

    // Surrounds the contents of this range with the given element,
putting it
    // in their place in the document and setting the range to contain
it.
    void surroundContents(Element copyInto);
    Element surroundContents(); // same but creates a span element for
you


    // A static utility function that should be part of Text or Node
class
    // Returns the next (or previous) text node, given an existing
Text node
    // or any other type of element
    Text getAdjacentTextNode(Node current, boolean forward);
}

// Represents a Range endpoint, a text node and offset into it.
class RangeEndPoint implements Comparable<RangeEndPoint>
{
    // Constructors
    RangeEndPoint(Text text, int offset);
    RangeEndPoint(Text text, boolean start);
    RangeEndPoint(Element element, boolean start);

    Text getTextNode();
    int getOffset();

    void setTextNode(Text textNode);
    void setTextNode(Text textNode, boolean start);
    void setOffset(int offset);
    void setElement(Element element, boolean start);

    // Get the string either before or after the offset point
    String getString(boolean asStart);
}

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to