/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.gwt.user.client.ui.internal; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.impl.TextBoxImpl; /** * Extends the text box implementation provided by GWT for IE with the ability to access and modify the selection * (cursor position and selection length) even when the text box doesn't have the focus. * * @version $Id: 6d292b73f46b59484e82b395c81f67391943e050 $ */ public class TextBoxImplIEOld extends TextBoxImpl { /** * The name of the property that preserves the selection length. */ private static final String SELECTION_LENGTH = "__selectionLength"; /** * The name of the property that preserved the cursor position. */ private static final String CURSOR_POS = "__cursorPos"; /** * The name of the flag that specifies if the selection is preserver on a given element. */ private static final String SELECTION_PRESERVED = "__selectionPreserved"; @Override public int getSelectionLength(Element element) { if (isFocused(element)) { return super.getSelectionLength(element); } else { return element.getPropertyInt(SELECTION_LENGTH); } } @Override public int getTextAreaCursorPos(Element element) { if (isFocused(element)) { return super.getTextAreaCursorPos(element); } else { return element.getPropertyInt(CURSOR_POS); } } @Override public void setSelectionRange(Element element, int pos, int length) { if (!element.getPropertyBoolean(SELECTION_PRESERVED)) { element.setPropertyBoolean(SELECTION_PRESERVED, true); ensureSelectionIsPreserved(element); } if (isFocused(element)) { super.setSelectionRange(element, pos, length); } else { element.setPropertyInt(CURSOR_POS, pos); element.setPropertyInt(SELECTION_LENGTH, length); } } /** * @param element a DOM element * @return {@code true} if the given element is focused, {@code false} otherwise */ private native boolean isFocused(Element element) /*-{ return element.ownerDocument.selection.createRange().parentElement() == element; }-*/; /** * Ensures the selection of the given element (e.g. a text area, a text input) is preserved when the element looses * focus. This method is required because in IE we can't access the cursor position or the selection length while * the element is not focused. * * @param element the element (e.g. a text area) whose selection had to be preserved */ public native void ensureSelectionIsPreserved(Element element) /*-{ var self = this; // Restore the selection before the element is focused. element.attachEvent('onbeforeactivate', function(event) { self.@org.xwiki.gwt.user.client.ui.internal.TextBoxImplIEOld::restoreSelection(Lcom/google/gwt/dom/client/Element;)(element); }); // Save the selection before the element loses the focus. element.attachEvent('onbeforedeactivate', function(event) { self.@org.xwiki.gwt.user.client.ui.internal.TextBoxImplIEOld::saveSelection(Lcom/google/gwt/dom/client/Element;)(element); }); }-*/; /** * Restores the selection inside the given element (e.g. text area, text input). If there's no saved selection the * caret is placed at the start. * * @param element the element whose selection is restored. */ private void restoreSelection(Element element) { setSelectionRange(element, element.getPropertyInt(CURSOR_POS), element.getPropertyInt(SELECTION_LENGTH)); } /** * Saves the selection start and the selection length. * * @param element the element whose selection is saved */ private void saveSelection(Element element) { element.setPropertyInt(CURSOR_POS, getTextAreaCursorPos(element)); element.setPropertyInt(SELECTION_LENGTH, getSelectionLength(element)); } }