/* * Copyright 2010 John Kozura * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.bfr.client.selection; import com.bfr.client.selection.impl.RangeImpl; import com.bfr.client.selection.impl.SelectionImpl; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.Document; /** * A selection within a particular document. Holds the singleton for a * particlar document/window for getting and setting the selection. * * @author John Kozura */ public final class Selection { public static final String START_NODE = "startContainer"; public static final String START_OFFSET = "startOffset"; public static final String END_NODE = "endContainer"; public static final String END_OFFSET = "endOffset"; public static final String IS_COLLAPSED = "isCollapsed"; /** * Clears or removes any current text selection. */ public static void clearAnySelectedText() { getSelection().clear(); } /** * Convenience for getting the range for the current browser selection * * @return A range object representing the browser window's selection */ public static Range getBrowserRange() { return getSelection().getRange(); } /** * Returns the selection for a given window, for instance an iframe * * @return The singleton instance */ static public Selection getSelection(JavaScriptObject window) { SelectionImpl.JSSel jsSel = c_impl.getSelection(window); Selection res = new Selection(); res.m_selection = jsSel; res.m_document = getDocument(window); return res; } public static native Document getDocument(JavaScriptObject window) /*-{ return window.document; }-*/; private SelectionImpl.JSSel m_selection; private Document m_document; /** * The browser aware support that takes care of browser difference nasties. */ private static SelectionImpl c_impl = (SelectionImpl) GWT.create(SelectionImpl.class); /** * Returns the document Selection singleton * * @return The singleton instance */ static public Selection getSelection() { return Selection.getSelection(getWindow()); } static SelectionImpl getImpl() { return Selection.c_impl; } static native private JavaScriptObject getWindow() /*-{ return $wnd; }-*/; protected Selection() { super(); } /** * Clears any current selection. */ public void clear() { Selection.getImpl().clear(m_selection); } /** * Gets the parent document associated with this selection. Could be * different from the browser document if, for example this is the selection * within an iframe. * * @return parent document of this selection */ public Document getDocument() { return m_document; } /** * Get the javascript object representing the selection. Since this is * browser dependent object, should probably not use this. * * @return a JavaScriptObject representing this selection */ public SelectionImpl.JSSel getJSSelection() { return m_selection; } /** * Gets the range associated with the given selection. The endpoints are * captured immediately, so any changes to the selection will not affect * the returned range. In some browsers (IE) this can return NULL if * nothing is selected in the document. * * @return A range object capturing the current selection */ public Range getRange() { Range res = null; RangeImpl.JSRange jsRange = c_impl.getJSRange(m_document, m_selection); if (jsRange != null) { res = new Range(m_document, jsRange); res.ensureEndPoints(); } return res; } /** * Tests if anything is currently being selected * * @return True if empty false otherwise */ public boolean isEmpty() { return Selection.getImpl().isEmpty(m_selection); } /** * Takes a range object and pushes it to be the new selection. The range * must be parented by the same window/document as the selection. The range * remains separate from the selection after this operation; any changes to * the range are not reflected in the selection, and vice versa. * * @param newSelection What the selection should be */ public void setRange(Range newSelection) { if (newSelection.getDocument() == m_document) { c_impl.setJSRange(m_selection, newSelection.getJSRange()); } } }