1 package autotest.common; 2 3 import com.google.gwt.event.logical.shared.ValueChangeEvent; 4 import com.google.gwt.event.logical.shared.ValueChangeHandler; 5 import com.google.gwt.user.client.History; 6 7 import java.util.ArrayList; 8 import java.util.HashMap; 9 import java.util.List; 10 import java.util.Map; 11 12 /** 13 * Wrapper around gwt.user.client.History that won't call onHistoryChanged for 14 * programmatically-generated history items. 15 * 16 */ 17 public class CustomHistory implements ValueChangeHandler<String> { 18 private static final CustomHistory theInstance = new CustomHistory(); 19 20 public static class HistoryToken extends HashMap<String, String> { 21 @Override toString()22 public String toString() { 23 return Utils.encodeUrlArguments(this); 24 } 25 fromString(String tokenString)26 public static HistoryToken fromString(String tokenString) { 27 HistoryToken token = new HistoryToken(); 28 Utils.decodeUrlArguments(tokenString, token); 29 return token; 30 } 31 } 32 33 private List<CustomHistoryListener> listeners = new ArrayList<CustomHistoryListener>(); 34 private HistoryToken lastHistoryToken = new HistoryToken(); 35 36 public static interface CustomHistoryListener { onHistoryChanged(Map<String, String> arguments)37 public void onHistoryChanged(Map<String, String> arguments); 38 } 39 CustomHistory()40 private CustomHistory() { 41 History.addValueChangeHandler(this); 42 } 43 44 /** 45 * Allows programmatic simulation of history changes, without actually changing history or the 46 * URL. 47 */ simulateHistoryToken(HistoryToken token)48 public static void simulateHistoryToken(HistoryToken token) { 49 theInstance.processHistoryTokenString(token.toString()); 50 } 51 processInitialToken()52 public static void processInitialToken() { 53 theInstance.processHistoryTokenString(History.getToken()); 54 } 55 56 @Override onValueChange(ValueChangeEvent<String> event)57 public void onValueChange(ValueChangeEvent<String> event) { 58 processHistoryTokenString(event.getValue()); 59 } 60 processHistoryTokenString(String historyTokenString)61 private void processHistoryTokenString(String historyTokenString) { 62 HistoryToken token; 63 try { 64 token = HistoryToken.fromString(historyTokenString); 65 } catch (IllegalArgumentException exc) { 66 return; 67 } 68 69 if (token.equals(lastHistoryToken)) { 70 return; 71 } 72 73 lastHistoryToken = token; 74 75 for (CustomHistoryListener listener : listeners) { 76 listener.onHistoryChanged(token); 77 } 78 } 79 getLastHistoryToken()80 public static HistoryToken getLastHistoryToken() { 81 return theInstance.lastHistoryToken; 82 } 83 addHistoryListener(CustomHistoryListener listener)84 public static void addHistoryListener(CustomHistoryListener listener) { 85 theInstance.listeners.add(listener); 86 } 87 removeHistoryListener(CustomHistoryListener listener)88 public static void removeHistoryListener(CustomHistoryListener listener) { 89 theInstance.listeners.remove(listener); 90 } 91 newItem(HistoryToken token)92 public static void newItem(HistoryToken token) { 93 if (token.equals(getLastHistoryToken())) { 94 return; 95 } 96 theInstance.lastHistoryToken = token; 97 History.newItem(token.toString()); 98 } 99 } 100