/*
* DomUtilsIE10Impl.java
*
* Copyright (C) 2009-12 by RStudio, Inc.
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.core.client.dom.impl;
import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import org.rstudio.core.client.Rectangle;
import org.rstudio.core.client.dom.ElementEx;
public class DomUtilsIE10Impl implements DomUtilsImpl
{
public void focus(Element element, boolean alwaysDriveSelection)
{
ElementEx el = (ElementEx) element;
el.focus();
}
public native final void collapseSelection(boolean toStart) /*-{
var rng = document.selection.createRange();
rng.collapse(toStart);
}-*/;
public native final boolean isSelectionCollapsed() /*-{
var rng = document.selection.createRange();
var testRng = rng.duplicate();
testRng.collapse(true);
return rng.isEqual(testRng);
}-*/;
public native final boolean isSelectionInElement(Element element) /*-{
var rng = element.ownerDocument.selection.createRange();
var el = rng.parentElement();
while (el != null)
{
if (el === element)
return true ;
el = el.parentNode ;
}
return false ;
}-*/;
private native String getSelectionType() /*-{
return document.selection.type;
}-*/;
public boolean selectionExists()
{
return !("None".equals(getSelectionType())) && !isSelectionCollapsed();
}
public Rectangle getCursorBounds(Document doc)
{
JsArrayInteger result = getSelectionBoundsInternal(doc);
return new Rectangle(
result.get(0),
result.get(1),
result.get(2),
result.get(3)
);
}
private native JsArrayInteger getSelectionBoundsInternal(Document doc) /*-{
var rng = doc.selection.createRange();
return [
rng.boundingLeft,
rng.boundingTop,
rng.boundingWidth,
rng.boundingHeight];
}-*/;
private native final Element getSelectionParentElement(Document doc) /*-{
return doc.selection.createRange().parentElement();
}-*/;
public native final String replaceSelection(Document doc,
String text) /*-{
var rng = doc.selection.createRange();
var orig = rng.text;
var html = @org.rstudio.core.client.dom.DomUtils::textToHtml(Ljava/lang/String;)(text);
rng.pasteHTML(html);
rng.select();
return orig;
}-*/;
public native final String getSelectionText(Document document) /*-{
var rng = doc.selection.createRange();
return rng.text;
}-*/;
public int[] getSelectionOffsets(Element container)
{
if (!isSelectionInElement(container))
return null;
JsArrayInteger results = getSelectionOffsetsJs(container);
if (results == null)
return null;
else
return new int[] {results.get(0), results.get(1)};
}
private native final JsArrayInteger getSelectionOffsetsJs(
Element container) /*-{
var rng = container.ownerDocument.body.createTextRange();
rng.moveToElementText(container);
rng.collapse(true);
var sel = container.ownerDocument.selection.createRange();
var startOffset = 0;
var endOffset = 0;
// Ideally this would be a binary search instead of linear probing
while (rng.compareEndPoints("EndToEnd", sel) < 0) {
rng.moveEnd("character");
startOffset++;
}
while (rng.compareEndPoints("StartToStart", sel) < 0) {
rng.moveStart("character");
endOffset++;
}
if (!rng.isEqual(sel))
return null;
else
return [startOffset, endOffset];
}-*/;
public native final void setSelectionOffsets(Element container,
int start,
int end) /*-{
var rng = container.ownerDocument.body.createTextRange();
rng.moveToElementText(container);
for (var i = 0; i < end; i++)
rng.moveEnd('character');
for (var j = 0; j < start; j++)
rng.moveStart('character');
var containerRng = container.ownerDocument.body.createTextRange();
containerRng.moveToElementText(container);
if (rng.compareEndPoints('EndToEnd', containerRng) > 0) {
rng.setEndPoint('EndToEnd', containerRng);
}
rng.select();
container.focus();
}-*/;
public boolean isSelectionAsynchronous()
{
return true;
}
@Override
public void selectElement(Element el)
{
throw new UnsupportedOperationException("DomUtilsIE8Impl.selectElement not implemented");
}
}