| /******************************************************************************* |
| * Copyright (c) 2006 Sybase, Inc. and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Sybase, Inc. - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.pagedesigner.commands.range; |
| |
| import java.util.Stack; |
| import java.util.Vector; |
| |
| import org.eclipse.gef.GraphicalViewer; |
| import org.eclipse.jst.jsf.common.ui.internal.logging.Logger; |
| import org.eclipse.jst.jsf.core.internal.tld.IJSFConstants; |
| import org.eclipse.jst.pagedesigner.IHTMLConstants; |
| import org.eclipse.jst.pagedesigner.PDPlugin; |
| import org.eclipse.jst.pagedesigner.dom.DOMPosition; |
| import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper; |
| import org.eclipse.jst.pagedesigner.dom.DOMRange; |
| import org.eclipse.jst.pagedesigner.dom.DOMRefPosition; |
| import org.eclipse.jst.pagedesigner.dom.EditHelper; |
| import org.eclipse.jst.pagedesigner.dom.EditModelQuery; |
| import org.eclipse.jst.pagedesigner.dom.IDOMPosition; |
| import org.eclipse.jst.pagedesigner.validation.caret.ActionData; |
| import org.eclipse.jst.pagedesigner.validation.caret.IETablePositionRule; |
| import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator; |
| import org.eclipse.jst.pagedesigner.viewer.LayoutPart; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.w3c.dom.Text; |
| |
| /** |
| * @author mengbo |
| */ |
| public class DeleteEdit extends DesignEdit { |
| private static final Logger _log = PDPlugin.getLogger(DeleteEdit.class); |
| |
| private static final boolean INNER_DEBUG = false; |
| |
| private boolean _forward; |
| |
| Vector deleted = new Vector(); |
| |
| /** |
| * @param range |
| * @param viewer |
| * @param forward |
| */ |
| public DeleteEdit(DOMRange range, GraphicalViewer viewer, boolean forward) { |
| super(range, viewer); |
| _forward = forward; |
| } |
| |
| /** |
| * @param range |
| * @param viewer |
| */ |
| public DeleteEdit(DOMRange range, GraphicalViewer viewer) { |
| super(range, viewer); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.commands.range.DesignEdit#operate() |
| */ |
| protected boolean operate() { |
| try { |
| boolean result = true; |
| if (EditModelQuery.isSame(getRange())) { |
| deleteSingle(); |
| } else { |
| deleteRange(); |
| } |
| return result; |
| } catch (Exception e) { |
| _log.error("Exception", e); //$NON-NLS-1$ |
| return false; |
| } |
| } |
| |
| /** |
| * Delete one node or char at operation position. |
| */ |
| private void deleteSingle() { |
| IDOMPosition opPosition = getOperationPosition(); |
| opPosition = EditHelper.moveToNextEditPosition(getOperationPosition(), |
| _forward, new InlineEditingNavigationMediator(new ActionData( |
| ActionData.INLINE_EDIT, null))); |
| // for inner debug |
| if (INNER_DEBUG) { |
| _log.info("EditHelper, now we are at:" + opPosition); //$NON-NLS-1$ |
| } |
| if (EditModelQuery.isSame(opPosition, getOperationPosition())) { |
| return; |
| } |
| setRange(new DOMRange(opPosition, getOperationPosition())); |
| deleteRange(); |
| } |
| |
| /** |
| * @return the stack |
| */ |
| protected Stack deleteRange() { |
| WorkNode root = getRootWorkNode(); |
| Node rootNode = root.getNode(); |
| Stack result = getProcessedResult(); |
| collectOtherStyles(rootNode, result); |
| return result; |
| } |
| |
| private boolean isTableComponents(WorkNode node) { |
| String name = node.getNode().getNodeName(); |
| return (IHTMLConstants.TAG_TD.equalsIgnoreCase(name) || // |
| IHTMLConstants.TAG_TH.equalsIgnoreCase(name) || // |
| IHTMLConstants.TAG_TR.equalsIgnoreCase(name) || // |
| IHTMLConstants.TAG_THEAD.equalsIgnoreCase(name) || // |
| IHTMLConstants.TAG_TBODY.equalsIgnoreCase(name) || // |
| IHTMLConstants.TAG_TFOOT.equalsIgnoreCase(name)); |
| } |
| |
| private Node processContainerTable(WorkNode node) { |
| Node result = null; |
| if ((isTableComponents(node) || IHTMLConstants.TAG_TABLE |
| .equalsIgnoreCase(node.getNode().getNodeName())) // |
| && new IETablePositionRule(null).isInValidTable(node |
| .getNode())) { |
| result = node.getNode().cloneNode(false); |
| } |
| return result; |
| } |
| |
| private Node processContainerStyleNodes(WorkNode node) { |
| String name = node.getNode().getNodeName(); |
| Node result = null; |
| if (IHTMLConstants.TAG_LI.equalsIgnoreCase(name) || // |
| EditModelQuery.HTML_STYLE_NODES.contains(node.getNode() |
| .getLocalName())) { |
| if (node.getNode().hasChildNodes()) { |
| result = node.getNode().cloneNode(false); |
| } |
| } |
| return result; |
| } |
| |
| private Node processContainerView(WorkNode node) { |
| Node result = null; |
| if (IJSFConstants.TAG_VIEW.equalsIgnoreCase(node.getNode() |
| .getLocalName())) { |
| result = EditModelQuery.getDocumentNode(node.getNode()) |
| .createElement(IJSFConstants.TAG_SUBVIEW); |
| result.setPrefix(node.getNode().getPrefix()); |
| } else if (IHTMLConstants.TAG_BODY.equalsIgnoreCase(node.getNode() |
| .getNodeName()) |
| || IHTMLConstants.TAG_HTML.equalsIgnoreCase(node.getNode() |
| .getNodeName())) { |
| result = EditModelQuery.getDocumentNode(node.getNode()) |
| .createElement(node.getNode().getNodeName()); |
| } |
| return result; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.commands.range.AbstractCopyEdit#processContainer(org.eclipse.jst.pagedesigner.commands.range.WorkNode) |
| */ |
| protected Node processContainer(WorkNode node) { |
| Node result = processContainerView(node); |
| if (result == null) { |
| result = processContainerTable(node); |
| } |
| if (result == null) { |
| result = processContainerStyleNodes(node); |
| } |
| if (result == null) { |
| // strip out container |
| if (LayoutPart.getConcreteNode(node.getNode()) != null) { |
| Node parent = node.getNode().getParentNode(); |
| Node refNode = node.getNode(); |
| Node child = node.getNode().getFirstChild(); |
| Node first = null, last = null; |
| int index = 0; |
| NodeList children = node.getNode().getChildNodes(); |
| int size = children.getLength(); |
| while (child != null) { |
| Node next = child.getNextSibling(); |
| Node n = EditHelper.deleteNode(child); |
| parent.insertBefore(n, refNode); |
| if (index == 0) { |
| if (refNode != null) { |
| first = refNode.getPreviousSibling(); |
| } else { |
| first = parent.getLastChild(); |
| } |
| } |
| if (index == size - 1) { |
| if (refNode != null) { |
| last = refNode.getPreviousSibling(); |
| } else { |
| last = parent.getLastChild(); |
| } |
| } |
| index++; |
| child = next; |
| } |
| if (node.getPosOffsets()[0] <= 0) { |
| setOperationPosition(new DOMRefPosition(first, false)); |
| } else { |
| setOperationPosition(new DOMRefPosition(last, true)); |
| } |
| } else { |
| setOperationPosition(new DOMRefPosition(node.getNode(), false)); |
| } |
| result = EditHelper.deleteNode(node.getNode()); |
| } |
| return result; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.commands.range.AbstractCopyEdit#processNode(org.w3c.dom.Node, |
| * int[]) |
| */ |
| protected Node processNode(WorkNode node) { |
| Node result = null; |
| if (!isTableComponents(node) |
| || !new IETablePositionRule(null).isInValidTable(node |
| .getNode())) { |
| // it's not table components. |
| setOperationPosition(new DOMRefPosition(node.getNode(), false)); |
| result = EditHelper.deleteNode(node.getNode()); |
| } |
| return result; |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.commands.range.AbstractCopyEdit#processText(org.w3c.dom.Text, |
| * int[]) |
| */ |
| protected Text processText(WorkNode node) { |
| Text currentNode = (Text) node.getNode(); |
| int[] offsets = node.getPosOffsets(); |
| Node second = null; |
| int location1 = EditHelper.getInstance().getLocation(currentNode, |
| node.getPosOffsets()[0], true); |
| int location2 = EditHelper.getInstance().getLocation(currentNode, |
| node.getPosOffsets()[1], true); |
| // left index |
| if (currentNode.getData().length() > 0) { |
| if (location1 == EditHelper.IN_MIDDLE) { |
| IDOMPosition position = new DOMPosition(currentNode, node |
| .getPosOffsets()[0]); |
| setOperationPosition(position); |
| position = DOMPositionHelper.splitText(position); |
| Node nnode = position.getNextSiblingNode(); |
| if (nnode instanceof Text) { |
| currentNode = (Text) nnode; |
| offsets[1] -= offsets[0] > 0 ? offsets[0] : 0; |
| } |
| } else { |
| // setOperationPosition(new DOMRefPosition(currentNode, false)); |
| if (currentNode.getPreviousSibling() != null) { |
| setOperationPosition(new DOMRefPosition(currentNode |
| .getPreviousSibling(), true)); |
| } else { |
| setOperationPosition(new DOMPosition(currentNode |
| .getParentNode(), 0)); |
| } |
| } |
| // right index |
| if (location2 >= EditHelper.IN_MIDDLE) { |
| IDOMPosition position = new DOMPosition(currentNode, offsets[1]); |
| position = DOMPositionHelper.splitText(position); |
| second = position.getPreviousSiblingNode(); |
| } |
| return second != null ? (Text) EditHelper.deleteNode(second) : null; |
| } |
| setOperationPosition(new DOMRefPosition(currentNode, false)); |
| return (Text) EditHelper.deleteNode(currentNode); |
| } |
| } |