/**
* Copyright 2010 Google 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.waveprotocol.wave.client.doodad.diff;
import org.waveprotocol.wave.client.editor.content.AnnotationPainter;
import org.waveprotocol.wave.client.editor.content.AnnotationPainter.BoundaryFunction;
import org.waveprotocol.wave.client.editor.content.AnnotationPainter.PaintFunction;
import org.waveprotocol.wave.client.editor.content.ContentElement;
import org.waveprotocol.wave.client.editor.content.DiffHighlightingFilter;
import org.waveprotocol.wave.client.editor.content.DiffHighlightingFilter.DeleteInfo;
import org.waveprotocol.wave.client.editor.content.PainterRegistry;
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.document.util.LocalDocument;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.ReadableStringSet;
import java.util.Collections;
import java.util.Map;
/**
* Defines behaviour for rendering diffs
*
* @author danilatos@google.com (Daniel Danilatos)
*/
public class DiffAnnotationHandler implements AnnotationMutationHandler {
/** Colour used for diff hilights of new content. */
private static final String HILIGHT_COLOUR = "yellow";
/** Annotation key prefix. */
public static final String PREFIX = DiffHighlightingFilter.DIFF_KEY;
/** Set of annotation keys that the paint function is interested in. */
private final static ReadableStringSet PAINT_KEYS =
CollectionUtils.newStringSet(DiffHighlightingFilter.DIFF_INSERT_KEY);
/** Set of annotation keys that the boundary function is interested in. */
private final static ReadableStringSet BOUNDARY_KEYS =
CollectionUtils.newStringSet(DiffHighlightingFilter.DIFF_DELETE_KEY);
/** Map of annotations for the diff paint renderer. */
private final static Map<String, String> PAINT_PROPERTIES =
Collections.singletonMap("backgroundColor", HILIGHT_COLOUR);
/**
* Create and register a style annotation handler
*
* @param annotationRegistry registry to register on
* @param painterRegistry painter registry to use for rendering
*/
public static void register(AnnotationRegistry annotationRegistry,
PainterRegistry painterRegistry) {
painterRegistry.registerPaintFunction(PAINT_KEYS, paintFunc);
painterRegistry.registerBoundaryFunction(BOUNDARY_KEYS, boundaryFunc);
annotationRegistry.registerHandler(PREFIX,
new DiffAnnotationHandler(painterRegistry.getPainter()));
}
/** Painter to access regional repainting of diff areas. */
private final AnnotationPainter painter;
/**
* Paint function for normal diffs, sets the background colour of the new
* content .
*/
private static final PaintFunction paintFunc = new PaintFunction() {
public Map<String, String> apply(Map<String, Object> from, boolean isEditing) {
if (from.get(DiffHighlightingFilter.DIFF_INSERT_KEY) != null) {
return PAINT_PROPERTIES;
} else {
return Collections.emptyMap();
}
}
};
/** Paint function for diff deletions. */
private static final BoundaryFunction boundaryFunc = new BoundaryFunction() {
public <N, E extends N, T extends N> E apply(LocalDocument<N, E, T> localDoc, E parent,
N nodeAfter, Map<String, Object> before, Map<String, Object> after, boolean isEditing) {
Object obj = after.get(DiffHighlightingFilter.DIFF_DELETE_KEY);
if (obj != null) {
// HACK(danilatos): Assume the elements are of this implementation.
assert obj instanceof DeleteInfo : "delete key's value must be a DeleteInfo";
// find the element, then set internal deleted content in the DOM
E elt = localDoc.transparentCreate(DiffDeleteRenderer.FULL_TAGNAME,
Collections.<String,String>emptyMap(), parent, nodeAfter);
DiffDeleteRenderer.getInstance().setInnards((ContentElement) elt,
((DeleteInfo) obj).getDeletedHtmlElements());
return elt;
} else {
return null;
}
}
};
/**
* Construct the handler, registering its rendering functions with the painter.
* @param painter painter to use for rendering
*/
public DiffAnnotationHandler(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);
}
}