0

I am trying to prevent a user from writing on a contentedtiable element. For this purpose I am retrieving the parent container of the caret and check if it is the textarea with ID dnd-textarea.

The code below works perfectly fine on Chrome but fails on Firefox. The logging output of preventWritingOnTextArea() reveals that under Firefox the parent didn't change but is still dnd-textarea instead of the InlinePanel with ID newId.

private native Node getCaretParent() /*-{

    var target = null;

    if($wnd.getSelection) {
        target = $wnd.getSelection().getRangeAt(0).commonAncestorContainer;
        return ((target.nodeType===1) ? target:target.parentNode);
    }
    else if($doc.selection) {
        target = $doc.selection.createRange().parentElement();
    }

    return target;
}-*/;

In the onKeyPress() method of my textarea I check if the carret tries to write on it. If so, I branch into preventWritingOnTextArea() to prevent that.

@Override
public void onKeyPress(KeyPressEvent event) {

    Node parent = getCaretParent();

    GWT.log("Caret parent: " + parent);

    if(parent == textarea.getElement()) {                       
        preventWritingOnTextArea();         
    }           
}

The method preventWritingOnTextAread() is supposed to add a new InlinePanel and remove the focus from the textarea by setting focus on this new panel. Imho this can only mean that focus() does not work on Firefox as expected and/or does something else.

private void preventWritingOnTextArea() {

    GWT.log("preventWritingOnTextArea()");

    InlineLabel textWrapper = new InlineLabel();

    int pos = getCursorPosition(textarea.getElement());

    if(pos == 0) {
        textarea.getElement().insertFirst(textWrapper.getElement());
    } else {
        textarea.getElement().appendChild(textWrapper.getElement());
    }

    String newId = "wrap-"+(nextId++);

    // Tried that too but this loses the focus completely under Firefox.
    //textarea.getElement().blur();

    textWrapper.getElement().setId(newId);
    textWrapper.getElement().focus();   

    Node parent = getCaretParent(); 
    Element newParent = parent.cast();  
    GWT.log("New parent " + newParent.getId());
}

How can I make this work under Firefox and yeah.. all the other browser too..

Yes, I have tried to blur() first on textarea and then set focus back on textWrapper but that didn't work as well.

Stefan Falk
  • 23,898
  • 50
  • 191
  • 378

1 Answers1

0

Well, Firefox did not want to do it the way it was supposed to work. My solution for now is to mark the text of new span element (which is obviously empty) to actually get the focus on it. It is ugly but then again we are talking here about web-development, right? Credits to @TimDown for this answer.

private void preventWritingOnTextArea() {

    GWT.log("preventWritingOnTextArea()");

    InlineLabel textWrapper = new InlineLabel();

    // ...

    textWrapper.getElement().setId(newId);
    textWrapper.getElement().focus();

    // Firefox didn't want to play with us.
    markText(textWrapper.getElement());
}

private native void markText(Element element) /*-{

    win = $wnd;
    var doc = win.document, sel, range;

    if (win.getSelection && doc.createRange) {      
        sel = win.getSelection();
        range = doc.createRange();
        range.selectNodeContents(element);
        sel.removeAllRanges();
        sel.addRange(range);

    } else if (doc.body.createTextRange) {      
        range = doc.body.createTextRange();
        range.moveToElementText(element);
        range.select();
    }       
}-*/;
Community
  • 1
  • 1
Stefan Falk
  • 23,898
  • 50
  • 191
  • 378