package org.waveprotocol.wave.client.doodad.annotation; import java.util.HashMap; import java.util.Map; import org.waveprotocol.wave.client.common.util.JsoView; import org.waveprotocol.wave.client.doodad.annotation.jso.JsoAnnotationController; import org.waveprotocol.wave.client.doodad.annotation.jso.JsoRange; import org.waveprotocol.wave.client.editor.content.AnnotationPainter; import org.waveprotocol.wave.client.editor.content.AnnotationPainter.PaintFunction; import org.waveprotocol.wave.client.editor.content.ContentElement; import org.waveprotocol.wave.client.editor.content.ContentNode; import org.waveprotocol.wave.client.editor.content.PainterRegistry; import org.waveprotocol.wave.client.editor.content.Registries; import org.waveprotocol.wave.client.editor.content.misc.AnnotationPaint; import org.waveprotocol.wave.client.editor.content.misc.AnnotationPaint.EventHandler; import org.waveprotocol.wave.client.editor.content.misc.AnnotationPaint.MutationHandler; import org.waveprotocol.wave.model.document.AnnotationBehaviour.AnnotationFamily; import org.waveprotocol.wave.model.document.AnnotationBehaviour.DefaultAnnotationBehaviour; import org.waveprotocol.wave.model.document.AnnotationMutationHandler; import org.waveprotocol.wave.model.document.util.AnnotationRegistry; import org.waveprotocol.wave.model.document.util.DocumentContext; import org.waveprotocol.wave.model.util.CollectionUtils; import org.waveprotocol.wave.model.util.ReadableStringMap.ProcV; import com.google.gwt.user.client.Event; /** * Annotations handler configurable with {@link JsoAnnotationController} instances. * * @author Pablo Ojanguren (pablojan@gmail.com) * */ @Deprecated public class AnnotationHandler implements AnnotationMutationHandler { public interface Activator { public boolean shouldFireEvent(); } private static AnnotationHandler handlerInstance = null; private final AnnotationPainter painter; public static String getSafeKey(String key) { return key.replace("/", "-"); } /** * Logic to set paint attributes for the annotation (see {@link AnnotationPaint}). * Eventually, these attributes are rendered to HTML by {@link AnnotationSpreadRenderer}. */ private static class RenderFunc implements PaintFunction { private final String key; private final String styleClass; private final JsoView stylesInline; public RenderFunc(String key, String styleClass, JsoView stylesInline) { this.key = key; this.styleClass = styleClass; this.stylesInline = stylesInline; } public Map<String, String> apply(Map<String, Object> from, boolean isEditing) { Map<String, String> ret = new HashMap<String, String>(); for (String key : from.keySet()) { if (this.key.equals(key)) { String safeKey = getSafeKey(key); String safeValue = from.get(key).toString(); // <l:s value-comment="234235"> ret.put(AnnotationPaint.VALUE_ATTR_PREFIX + safeKey, safeValue); // <l:s eventListener-comment="comment"> ... </l:s> ret.put(AnnotationPaint.EVENT_LISTENER_ATTR_PREFIX + safeKey, key); // <l:s mutationListener-comment="comment"> ... </l:s> ret.put(AnnotationPaint.MUTATION_LISTENER_ATTR_PREFIX + safeKey, key); // <l:s class-comment="?"> .. </l:s> if (styleClass != null) ret.put(AnnotationPaint.CLASS_ATTR, styleClass); if (stylesInline != null) { stylesInline.each(new ProcV<String>() { @Override public void apply(String styleName, String styleValue) { ret.put(styleName, styleValue); } }); } } } return ret; } } /** * * * @param registries * @param key * @param mutationHanlder * @param eventHandler */ public static void register(Registries registries, String key, MutationHandler mutationHanlder, EventHandler eventHandler, String styleClass, JsoView stylesInline) { PainterRegistry painterRegistry = registries.getPaintRegistry(); if (handlerInstance == null) handlerInstance = new AnnotationHandler(painterRegistry.getPainter()); AnnotationRegistry annotationRegistry = registries.getAnnotationHandlerRegistry(); annotationRegistry.registerHandler(key, handlerInstance); annotationRegistry.registerBehaviour(key, new DefaultAnnotationBehaviour(AnnotationFamily.CONTENT)); // Register painter to update attributes of the local view painterRegistry.registerPaintFunction(CollectionUtils.newStringSet(key), new RenderFunc(key, styleClass, stylesInline)); if (eventHandler != null) AnnotationPaint.registerEventHandler(key, eventHandler); if (mutationHanlder != null) AnnotationPaint.setMutationHandler(key, mutationHanlder); // TODO (pablojan) Not sure if boundary functions are required //painterRegistry.registerBoundaryFunction(annotationNames, ); } public static void register(Registries registries, String key, JsoAnnotationController controller, Activator activator) { AnnotationHandler.register(registries, key, new AnnotationPaint.MutationHandler() { @Override public void onMutation(ContentElement node) { String valueAttr = AnnotationPaint.VALUE_ATTR_PREFIX + AnnotationHandler.getSafeKey(key); if (controller != null && activator.shouldFireEvent()) controller.onChange(JsoRange.Builder.create(node.getMutableDoc()).range(node).annotation(key, node.getAttribute(valueAttr)).build()); } @Override public void onAdded(ContentElement node) { String valueAttr = AnnotationPaint.VALUE_ATTR_PREFIX + AnnotationHandler.getSafeKey(key); if (controller != null && activator.shouldFireEvent()) controller.onAdd(JsoRange.Builder.create(node.getMutableDoc()).range(node).annotation(key, node.getAttribute(valueAttr)).build()); } @Override public void onRemoved(ContentElement node) { String valueAttr = AnnotationPaint.VALUE_ATTR_PREFIX + AnnotationHandler.getSafeKey(key); if (controller != null && activator.shouldFireEvent()) controller.onRemove(JsoRange.Builder.create(node.getMutableDoc()).range(node).annotation(key, node.getAttribute(valueAttr)).build()); } }, new AnnotationPaint.EventHandler() { @Override public void onEvent(ContentElement node, Event event) { String valueAttr = AnnotationPaint.VALUE_ATTR_PREFIX + AnnotationHandler.getSafeKey(key); if (controller != null && activator.shouldFireEvent()) controller.onEvent(JsoRange.Builder.create(node.getMutableDoc()).range(node).annotation(key, node.getAttribute(valueAttr)).build(), event); } }, controller != null ? controller.getStyleClass() : null, controller != null ? controller.getStylesInline() : JsoView.create()); } public AnnotationHandler(AnnotationPainter painter) { this.painter = painter; } @Override public <N, E extends N, T extends N> void handleAnnotationChange(DocumentContext<N, E, T> bundle, int start, int end, String key, Object newValue) { painter.scheduleRepaint(bundle, start, end); } public static boolean isAnnotationNode(ContentNode node) { ContentElement element = node.asElement(); if (element == null) return false; return element.getTagName().equals(AnnotationPaint.SPREAD_FULL_TAGNAME); } }