/** * 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.content.paragraph; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Node; import org.waveprotocol.wave.client.editor.content.ContentElement; import org.waveprotocol.wave.client.editor.content.ContentView; /** * Used for Gecko and Webkit * * Firefox, like Safari, uses a regular <br/> element as spacer. * * Firefox's native editor always preserves a br at the end of * each line as a spacer. * * Safari's native editor removes the spacer br by default for * non-empty lines, however this causes glitches. Given that it * works just to manually force it to always keep the br, and * that this fixes the glitches (to do with non-empty content * that still collapses the paragraph, such as a nested empty * span), we use this behaviour for Safari as well. * * Firefox's native editor: * * -- Adds the <br/> when creating new, empty paragraphs. * -- Adds the <br/> when the user deletes the last char in the paragraph. * -- Adds the <br/> when the user types a trailing space * -- Removes the <br/> when the user hits return at the end of a * non-empty paragraph * * but Firefox: * * -- Does *not* add the <br/> when we removeChild the last node from * a paragraph. * -- Does *not* add the <br/> when we createElement an empty paragraph * and insert it into the editor. * -- Does *not* add the <br> is we insert text with a trailing space into * the end of the paragraph * * Our code inserts and moves spacer <br/> elements to always have the * <br/> element at the end of the paragraph. (Note that we handle return * ourselves, so Firefox does not get a chance to remove the <br/> on return.) * */ public class ParagraphHelperAlwaysBr extends ParagraphHelperBr { /** * {@inheritDoc} */ @Override public void onChildAdded(Node child, Element paragraph) { appendSpacer(paragraph); } /** * {@inheritDoc} */ @Override public void onRemovingChild(Node child, Element paragraph) { appendSpacer(paragraph); } /** * {@inheritDoc} */ @Override public void onRepair(ContentElement paragraph) { appendSpacer(paragraph.getImplNodelet()); } /** * {@inheritDoc} */ @Override public void assertHealthy(ContentElement paragraph) { ContentView renderedContent = paragraph.getRenderedContentView(); if (renderedContent.getFirstChild(paragraph) != null) { Element nodelet = paragraph.getImplNodelet(); Node last = nodelet.getLastChild(); assert isSpacer(last) : "Last nodelet child should be spacer"; Node child = nodelet.getFirstChild(); while (child != null && !child.equals(last)) { assert !isSpacer(child) : "Only last nodelet child should be spacer"; child = child.getNextSibling(); } } super.assertHealthy(paragraph); } }