/******************************************************************************* * 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.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.jst.jsf.core.internal.tld.IJSFConstants; import org.eclipse.jst.pagedesigner.IHTMLConstants; import org.eclipse.jst.pagedesigner.dom.DOMPosition; import org.eclipse.jst.pagedesigner.dom.DOMRefPosition; import org.eclipse.jst.pagedesigner.dom.EditModelQuery; import org.eclipse.jst.pagedesigner.dom.IDOMPosition; import org.w3c.dom.Node; /** * @author mengbo */ public class BlockNodeFinder { private String[] _additionalTags; private IDOMPosition _position; /** * @param position * @param additionalTags */ public BlockNodeFinder(IDOMPosition position, String[] additionalTags) { _position = position; _additionalTags = additionalTags; } private Node findInlineSiblings(IDOMPosition position, List result, boolean forward) { Node container = EditModelQuery.getInstance().getSibling(position, forward); if (!forward) { while (container != null) { if (EditModelQuery.isInline(container)) { result.add(container); } else { return container; } container = container.getPreviousSibling(); } } else { while (container != null) { if (EditModelQuery.isInline(container)) { result.add(container); } else { return container; } container = container.getNextSibling(); } } // the result will be non-zero length. return null; } private Node getParagraphNodes(IDOMPosition position, List result, boolean forward) { Node sResult = findInlineSiblings(position, result, forward); Node container = position.getContainerNode(); container = position.isText() ? container.getParentNode() : container; while (sResult == null) { // stop at block, special container and H style nodes. if (EditModelQuery.isBlockNode(container) || EditModelQuery.isDocument(container) || (container.getLocalName() != null && (container .getLocalName().equals(IJSFConstants.TAG_VIEW) || container .getLocalName().equalsIgnoreCase( IHTMLConstants.TAG_HTML))) || // (_additionalTags != null && Arrays.asList(_additionalTags).contains( getTagName()) && Arrays.asList( _additionalTags).contains(container))) { return container; } position = new DOMRefPosition(container, forward); sResult = findInlineSiblings(position, result, forward); container = container.getParentNode(); } return sResult; } /** * Search for an area between two block nodes or within a block node, search * will stop before or under a node which has block display-type, or * particular container like "html", jsf "view", .etc, two positions (left * and right) are returned in result. * * The searcher will search parent's directly children, if no block node is * found, then go up the node tree to search again. * * @param position * @param result */ public void getParagraphNodes(IDOMPosition position, List result) { List tempResult = new ArrayList(); Node r1 = getParagraphNodes(position, tempResult, true); if (EditModelQuery.isChild(r1, position.getContainerNode())) { result.add(new DOMPosition(r1, r1.getChildNodes().getLength())); } else { result.add(new DOMRefPosition(r1, false)); } Node r2 = getParagraphNodes(position, tempResult, false); if (EditModelQuery.isChild(r2, position.getContainerNode())) { result.add(new DOMPosition(r2, 0)); } else { result.add(new DOMRefPosition(r2, true)); } } private String getTagName() { String name = _position.getContainerNode().getNodeName(); name = name == null ? "" : name.toLowerCase(); //$NON-NLS-1$ return name; } }