/* * 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 } }