/** * Copyright 2008 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.editor; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.Widget; import org.waveprotocol.wave.client.common.util.KeySignalListener; import org.waveprotocol.wave.client.editor.content.AnnotationPainter; import org.waveprotocol.wave.client.editor.content.ContentDocument; import org.waveprotocol.wave.client.editor.content.ContentView; import org.waveprotocol.wave.client.editor.content.PainterRegistry; import org.waveprotocol.wave.client.editor.content.PainterRegistryImpl; import org.waveprotocol.wave.client.editor.content.Registries; import org.waveprotocol.wave.client.editor.content.RegistriesImpl; import org.waveprotocol.wave.client.editor.content.misc.AnnotationPaint; import org.waveprotocol.wave.client.editor.keys.KeyBindingRegistry; import org.waveprotocol.wave.client.scheduler.SchedulerInstance; import org.waveprotocol.wave.model.document.operation.DocOp; import org.waveprotocol.wave.model.document.operation.DocInitialization; import org.waveprotocol.wave.model.document.operation.automaton.DocumentSchema; import org.waveprotocol.wave.model.document.util.AnnotationRegistryImpl; import org.waveprotocol.wave.model.operation.SilentOperationSink; import org.waveprotocol.wave.model.util.CollectionUtils; import org.waveprotocol.wave.model.util.StringSet; /** * Rich Text Editor interface class. Implementation in {@link EditorImpl} * * An editor is given a document to edit. The document may be added or removed from the * editor as desired. * * The purpose of the editor is to abstract away the difficulties of dealing * with a browser when editing a document of some arbitrary semantic model, * rendered into HTML. The editor translates low level browser events and * behaviour into high level events for custom content handlers to deal with in * a desired manner. * * Cleaner separation of these concerns is a matter of ongoing improvement * * @author danilatos@google.com (Daniel Danilatos) */ public interface Editor extends EditorContext { /** * Base handler registry for all editors */ public static final ElementHandlerRegistry ROOT_HANDLER_REGISTRY = ElementHandlerRegistry.ROOT; /** * Base annotation handler registry */ public static final AnnotationRegistryImpl ROOT_ANNOTATION_REGISTRY = AnnotationRegistryImpl.ROOT; /** * Painter registry */ public static final PainterRegistry ROOT_PAINT_REGISTRY = new PainterRegistryImpl( AnnotationPaint.SPREAD_FULL_TAGNAME, AnnotationPaint.BOUNDARY_FULL_TAGNAME, new AnnotationPainter( GWT.isClient() ? SchedulerInstance.getMediumPriorityTimer() : null)); /** * Base registry set */ public static final Registries ROOT_REGISTRIES = new RegistriesImpl(ROOT_HANDLER_REGISTRY, ROOT_ANNOTATION_REGISTRY, ROOT_PAINT_REGISTRY); /** * Declare a set of strings corresponding to tags that should * have special tabbing. */ public static StringSet TAB_TARGETS = CollectionUtils.newStringSet(); Widget getWidget(); /** * Initialises the editor (in display mode) * * @param registries The registries needed for rendering/handling elements and * annotations. */ void init(Registries registries, KeyBindingRegistry keys, EditorSettings settings); /** * Clears internal state, and makes this editor ready to be re-used. If this * editor is never to be re-used, use the stronger {@link #cleanup()} instead. * * Opposite of init() Called when an editor is not needed for display or * editing, but might be re-purposed later by a call to init(). * * TODO(hearnden/danilators): Consider a presenter/view separation for the * editor, to reduce the amount of state that needs to be reset here. */ void reset(); /** * Give the editor a sink to send outgoing operations to * @param sink */ void setOutputSink(SilentOperationSink<DocOp> sink); /** * Makes this editor forget any previously registered output sink. */ void clearOutputSink(); /** * @return true if the editor currently contains a document */ boolean hasDocument(); /** * @return the document element after the decorator */ Element getDocumentHtmlElement(); /** * Gets the document state as a tree-structured document. * The returned document represents (only) the result of the operation * history; it does not include transparent decorations or other transient * state. * * @return the document. */ ContentView getPersistentDocument(); //TODO(danilatos): Rename these to setDocument(), getDocument(), etc. /** * Sets the content in the editor from a doc initialization * * @param op An operation describing the document */ void setContent(final DocInitialization op, DocumentSchema schema); /** * Place an existing document into the editor * * @param doc An existing document */ void setContent(ContentDocument doc); /** * @return The editor's document as an operation to apply to something else. * Useful for serialisation, copying, etc. */ DocInitialization getDocumentInitialization(); /** * @return the current document being edited, or null if none */ ContentDocument getContent(); /** * Removes the editor's document * * @return the old document. It is still in render mode. */ ContentDocument removeContent(); /** * Removes the editor's document and return it in an unredered state. * * This is faster than calling {@link #removeContent()} and then * turning off rendering as separate steps. * * @return the old document. */ ContentDocument removeContentAndUnrender(); /** * Starts or stops editing * @param editing True is Editor should edit, * false if it should display */ void setEditing(boolean editing); /** * Must be called when an editor is no longer used anymore, to prevent memory * leaks */ void cleanup(); /** * Adds a listener for key signal events. * @param listener */ void addKeySignalListener(KeySignalListener listener); /** * Removes a key signal event listener. * @param listener */ void removeKeySignalListener(KeySignalListener listener); /** * Synchronously flushes any update events */ void flushUpdates(); /** * Show/hide the debug dialog */ void debugToggleDebugDialog(); /** * Synchronously flushes any annotation painting that may have been deferred. */ void flushAnnotationPainting(); /** * Runs any save selection tasks immediately rather than wait for them to be * triggered asynchronously. */ void flushSaveSelection(); }