/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.gwt.user.client.ui.rta.cmd.internal;
import org.xwiki.gwt.dom.client.Element;
import org.xwiki.gwt.dom.client.Property;
import org.xwiki.gwt.user.client.ui.rta.RichTextArea;
import com.google.gwt.dom.client.Node;
/**
* Looks for the nearest block-level elements from the current selection and applies a specific style to them.
*
* @version $Id: d55179a9c4043b89b3f4fa872f1aba2cb1bdcfac $
*/
public class BlockStyleExecutable extends AbstractBlockExecutable
{
/**
* The style property that is applied.
*/
private final Property property;
/**
* Creates a new instance that applies the given style property to the nearest block-level elements from the current
* selection in the specified rich text area.
*
* @param rta the execution target
* @param property the style property to be applied
*/
public BlockStyleExecutable(RichTextArea rta, Property property)
{
super(rta);
this.property = property;
}
/**
* {@inheritDoc}
* <p>
* Applies the underlying style property with the specified value to the nearest block-level ancestor of the given
* node.
* </p>
*
* @see AbstractStyleExecutable#execute(Node, int, int, String)
*/
@Override
protected void execute(Node node, int startOffset, int endOffset, String value)
{
Node ancestor = node;
int offset = startOffset;
if (domUtils.isInline(node)) {
ancestor = domUtils.getFarthestInlineAncestor(node);
offset = domUtils.getNodeIndex(ancestor);
ancestor = ancestor.getParentNode();
}
if (ancestor == ancestor.getOwnerDocument().getBody()) {
// We cannot apply the style property to the BODY element because only its contents are persisted when the
// edited document is saved; as a consequence all the attributes of the BODY element are dropped upon
// saving the edited document (including the style attribute).
// Let's wrap the in-line contents around the current selection in a paragraph.
ancestor = wrap((Element) ancestor, offset, "p");
}
addStyle(Element.as(ancestor), value);
}
/**
* Styles the given element.
*
* @param element the element to be styled
* @param value the value of the style property that is set
*/
protected void addStyle(Element element, String value)
{
element.getStyle().setProperty(property.getJSName(), value);
}
/**
* {@inheritDoc}
* <p>
* Returns the value of the underlying style property for the nearest block-level ancestor of the given node.
* </p>
*
* @see AbstractStyleExecutable#getParameter(Node)
*/
@Override
protected String getParameter(Node node)
{
Element element = (Element) domUtils.getNearestBlockContainer(node);
return element.getComputedStyleProperty(property.getJSName());
}
}