/** * */ package org.gcube.portlets.user.newsfeed.client.templates; import java.util.ArrayList; import org.gcube.portlets.user.gcubewidgets.client.elements.Div; import org.gcube.portlets.user.newsfeed.client.NewsService; import org.gcube.portlets.user.newsfeed.client.NewsServiceAsync; import org.gcube.portlets.user.newsfeed.client.panels.NewsFeedPanel; import org.gcube.portlets.widgets.pickuser.client.dialog.PickUsersDialog; import org.gcube.portlets.widgets.pickuser.client.events.PickedUserEvent; import org.gcube.portlets.widgets.pickuser.client.events.PickedUserEventHandler; import org.gcube.portlets.widgets.pickuser.shared.PickingUser; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Random; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.TextArea; /** * @author massi * */ public class SuperPosedTextArea extends TextArea { private final NewsServiceAsync newsService = GWT.create(NewsService.class); private final HandlerManager eventBus = new HandlerManager(null); private PickUsersDialog pickUserDlg; private Div highlighterDIV; public final static int ARROW_UP = 38; public final static int ARROW_DOWN = 40; private ArrayList mentionedUsers = new ArrayList(); private String areaId; /** * */ public SuperPosedTextArea(Div highlighterDIV) { sinkEvents(Event.ONPASTE); sinkEvents(Event.ONKEYUP); sinkEvents(Event.ONCONTEXTMENU); sinkEvents(Event.ONKEYDOWN); setText(AddCommentTemplate.COMMENT_TEXT); this.highlighterDIV = highlighterDIV; //needed to give unique identifiers to the Area (for the jQuery plugin) areaId = "postTextArea"+Random.nextInt(); newsService.getOrganizationUsers(NewsFeedPanel.getCurrentScope(), new AsyncCallback>() { @Override public void onSuccess(ArrayList users) { pickUserDlg = new PickUsersDialog(users, eventBus, 450); } @Override public void onFailure(Throwable caught) { } }); DOM.setElementAttribute(getElement(), "id", areaId); bind(); Timer t = new Timer() { @Override public void run() { myAutoSize(areaId); setCaretPositionToBegin(areaId); } }; t.schedule(200); } /** * This is the way to wrap jQuery plugins into GWT, wrap it in a function and call it. */ public static native void myAutoSize(String myAreaId) /*-{ function autoSizeArea() { $wnd.jQuery('#'+myAreaId).autosize(); } autoSizeArea(); }-*/; /** * @param element */ public SuperPosedTextArea(Element element) { super(element); } /** * paste event overridden */ public void onBrowserEvent(Event event) { super.onBrowserEvent(event); switch (event.getTypeInt()) { case Event.ONPASTE: { if (getText().equals(AddCommentTemplate.COMMENT_TEXT) || getText().equals(AddCommentTemplate.ERROR_UPDATE_TEXT) ) { setText(""); addStyleName("dark-color"); removeStyleName("error"); } break; } case Event.ONKEYUP: { injectInDiv(getText()); pickUserDlg.onKeyUp(event.getKeyCode(), this.getAbsoluteLeft(), this.getAbsoluteTop()+this.getOffsetHeight(), getText()); break; } case Event.ONCONTEXTMENU: { removeSampleText(); break; } case Event.ONKEYDOWN: { if (pickUserDlg.isShowing()) { //avoid the arrow up to move the cursor at the beginning of the textbox and the TAB to move around inputs and enter to go newline if (event.getKeyCode() == ARROW_UP || event.getKeyCode() == KeyCodes.KEY_TAB || event.getKeyCode() == KeyCodes.KEY_ENTER) { DOM.eventCancelBubble(event, true); DOM.eventPreventDefault(event); return; } } break; } } } protected void removeSampleText() { if (getText().equals(AddCommentTemplate.COMMENT_TEXT) || getText().equals(AddCommentTemplate.ERROR_UPDATE_TEXT) ) { setText(""); addStyleName("darker-color"); removeStyleName("error"); } } protected void cleanHighlighterDiv() { //DOM.getElementById("comment-highlighter").setInnerHTML(""); highlighterDIV.getElement().setInnerHTML(""); } /** * copy what is being written in the text area in the underneath DIV * @param textAreaText */ private void injectInDiv(String textAreaText) { String text; // parse the text: // replace all the line braks by
, and all the double spaces by the html version   text = textAreaText.replaceAll("(\r\n|\n)","
"); text = text.replaceAll("\\s\\s","  "); for (String mentionedUser : mentionedUsers) { text = text.replaceAll(mentionedUser,""+mentionedUser+""); } // re-inject the processed text into the div //DOM.getElementById("comment-highlighter").setInnerHTML(text); highlighterDIV.getElement().setInnerHTML(text); } /** * events binder */ private void bind() { eventBus.addHandler(PickedUserEvent.TYPE, new PickedUserEventHandler() { @Override public void onSelectedUser(PickedUserEvent event) { String toAdd = event.getSelectedUser().getFullName(); mentionedUsers.add(toAdd); String[] toSplit = getText().split("@"); //get the preceeding part setText(toSplit[0]+toAdd); //Element highDiv = DOM.getElementById("comment-highlighter"); Element highDiv = highlighterDIV.getElement(); String[] htmlToSplit = highDiv.getInnerHTML().split("@"); //get the preceeding part String highLightedUser = ""+toAdd+""; highDiv.setInnerHTML(htmlToSplit[0]+highLightedUser); } }); } public ArrayList getMentionedUsers() { ArrayList toReturn = new ArrayList(); for (String mentionedUser : mentionedUsers) { if (getText().contains(mentionedUser)) toReturn.add(mentionedUser); } GWT.log(toReturn.toString()); return mentionedUsers; } /** * this position the caret at the begin */ public static native void setCaretPositionToBegin(String myAreaId) /*-{ var elem = $doc.getElementById(myAreaId); if(elem != null) { if(elem.createTextRange) { var range = elem.createTextRange(); range.move('character', 0); range.select(); } else { if(elem.selectionStart) { elem.focus(); elem.setSelectionRange(0, 0); } else elem.focus(); } } }-*/; }