/*
* Copyright 2015 JBoss Inc
*
* 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 org.uberfire.ext.widgets.common.client.tables;
import com.google.common.base.Strings;
import com.google.gwt.cell.client.AbstractSafeHtmlCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.text.shared.SimpleSafeHtmlRenderer;
import com.google.gwt.user.client.DOM;
import static com.google.gwt.dom.client.BrowserEvents.MOUSEOUT;
import static com.google.gwt.dom.client.BrowserEvents.MOUSEOVER;
/**
* An extension to the normal TextCell that renders a Bootstrap Popover when text overflows.
*/
public class PopoverTextCell extends AbstractSafeHtmlCell<String> {
private Placement placement;
public PopoverTextCell(final Placement placement) {
super(SimpleSafeHtmlRenderer.getInstance(),
MOUSEOVER,
MOUSEOUT);
this.placement = placement;
}
public PopoverTextCell() {
this(Placement.AUTO);
}
@Override
protected void render(Context context,
SafeHtml data,
SafeHtmlBuilder sb) {
hideAllPopover();
final String content = data.asString();
if (Strings.isNullOrEmpty(content)) {
return;
}
final Element div = DOM.createDiv();
div.setId(DOM.createUniqueId());
div.setInnerHTML(content);
div.getStyle().setOverflow(Style.Overflow.HIDDEN);
div.getStyle().setTextOverflow(Style.TextOverflow.ELLIPSIS);
div.getStyle().setWhiteSpace(Style.WhiteSpace.NOWRAP);
final String html = div.getString();
sb.appendHtmlConstant(html);
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
initPopover(div.getId(),
placement.name().toLowerCase());
}
});
}
@Override
public void onBrowserEvent(final Context context,
final Element parent,
final String value,
final NativeEvent event,
final ValueUpdater<String> valueUpdater) {
super.onBrowserEvent(context,
parent,
value,
event,
valueUpdater);
final Element element = Element.as(event.getEventTarget());
if (DivElement.is(element) == false) {
return;
}
if (MOUSEOVER.equals(event.getType())) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
showPopover(parent.getFirstChildElement().getId());
}
});
} else if (MOUSEOUT.equals(event.getType())) {
hidePopover(parent.getFirstChildElement().getId());
}
}
private native void hideAllPopover() /*-{
$wnd.jQuery('.popover').popover('hide');
}-*/;
private native void hidePopover(String id) /*-{
$wnd.jQuery('#' + id).popover('hide');
}-*/;
private native void showPopover(String id) /*-{
$wnd.jQuery('#' + id).popover('show');
}-*/;
private native void initPopover(String id,
String placement) /*-{
var jQueryId = '#' + id;
var div = $wnd.jQuery(jQueryId);
div.popover({
trigger: 'manual',
placement: placement,
content: function () {
var offsetWidth = $wnd.document.getElementById(id).offsetWidth;
var scrollWidth = $wnd.document.getElementById(id).scrollWidth;
return offsetWidth < scrollWidth ? div.html() : "";
},
container: 'body'
});
}-*/;
public enum Placement {
LEFT,
TOP,
AUTO,
BOTTOM,
RIGHT
}
}