diff options
Diffstat (limited to 'jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java')
-rw-r--r-- | jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java | 1775 |
1 files changed, 0 insertions, 1775 deletions
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java deleted file mode 100644 index 85f43ba59..000000000 --- a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java +++ /dev/null @@ -1,1775 +0,0 @@ -/******************************************************************************* - * 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.dom; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Vector; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.gef.EditPart; -import org.eclipse.jface.text.TextSelection; -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.css2.ICSSStyle; -import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID; -import org.eclipse.jst.pagedesigner.parts.ElementEditPart; -import org.eclipse.jst.pagedesigner.parts.HTMLEditPartsFactory; -import org.eclipse.jst.pagedesigner.parts.NodeEditPart; -import org.eclipse.jst.pagedesigner.utils.HTMLUtil; -import org.eclipse.jst.pagedesigner.validation.caret.Target; -import org.eclipse.jst.pagedesigner.viewer.DesignPosition; -import org.eclipse.jst.pagedesigner.viewer.DesignRange; -import org.eclipse.swt.SWT; -import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; -import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; -import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; - -/** - * @author mengbo - */ -public class EditModelQuery { - private static Logger _log = PDPlugin.getLogger(EditModelQuery.class); - - private static EditModelQuery _instance; - - public static final int START_INDEX_BEFORE_TAG = 1; - - public static final int END_INDEX_WITHIN_TAG = 2; - - public static final HashSet SPECIAL_EMPTY_CHARS = new HashSet(); - - public static final HashMap CHAR_NODE_MAP = new HashMap(); - - // Cursor can't go outside of these container. - public static final HashSet HTML_CONSTRAINED_CONTAINERS = new HashSet(); - - public static final HashSet HTML_STYLE_NODES = new HashSet(); - - public static final HashSet UNREMOVEBLE_TAGS = new HashSet(); - - // Nodes that can hold other nodes. - public static final String[] HTML_CONTAINER_NODES = { - // - IHTMLConstants.TAG_BODY, // - IHTMLConstants.TAG_HTML, // - IHTMLConstants.TAG_SPAN, // - IHTMLConstants.TAG_FORM, // - IHTMLConstants.TAG_P,// - IHTMLConstants.TAG_SPAN,// - IHTMLConstants.TAG_DIV,// - IHTMLConstants.TAG_LI,// - IHTMLConstants.TAG_OL,// - IHTMLConstants.TAG_UL // - }; - - public static final String[] NON_HTML_CONTAINER_NODES = { - IJSFConstants.TAG_VIEW, // - IJSFConstants.TAG_PANELGRID, // - IJSFConstants.TAG_PANELGROUP, // - IJSFConstants.TAG_SUBVIEW }; - static { - UNREMOVEBLE_TAGS.add(IHTMLConstants.TAG_HTML); - UNREMOVEBLE_TAGS.add(IHTMLConstants.TAG_HEAD); - UNREMOVEBLE_TAGS.add(IHTMLConstants.TAG_BODY); - EditModelQuery.CHAR_NODE_MAP.put(new Character(SWT.CR), - IHTMLConstants.TAG_BR); - EditModelQuery.CHAR_NODE_MAP.put(new Character(SWT.LF), - IHTMLConstants.TAG_BR); - EditModelQuery.SPECIAL_EMPTY_CHARS.add(" "); - EditModelQuery.SPECIAL_EMPTY_CHARS.add("\t"); - EditModelQuery.SPECIAL_EMPTY_CHARS.add("\r"); - EditModelQuery.SPECIAL_EMPTY_CHARS.add("\n"); - EditModelQuery.HTML_CONSTRAINED_CONTAINERS.add(IHTMLConstants.TAG_TD); - EditModelQuery.HTML_CONSTRAINED_CONTAINERS.add(IHTMLConstants.TAG_TR); - EditModelQuery.HTML_CONSTRAINED_CONTAINERS - .add(IHTMLConstants.TAG_TABLE); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_B); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_EM); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H1); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H2); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H3); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H4); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H5); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H6); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_A); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_U); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_I); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_S); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_STRONG); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_TT); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_BIG); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_SMALL); - EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_FONT); - } - - private EditModelQuery() { - // no external instantiation - } - - public static EditModelQuery getInstance() { - if (_instance == null) { - _instance = new EditModelQuery(); - } - return _instance; - } - - /** - * Get previous sibling, or if sibling is null then get previous neighbor. - * - * @param node - * @return - */ - public Node getPreviousNeighbor(Node node) { - if (!EditValidateUtil.validNode(node)) { - return null; - } - while (node != null && node.getNodeType() != Node.DOCUMENT_NODE - && node.getPreviousSibling() == null) { - node = node.getParentNode(); - } - return (node != null && node.getNodeType() != Node.DOCUMENT_NODE) ? node - .getPreviousSibling() - : null; - } - - /** - * Get privous sibling, or if sibling is null then get previous neighor's - * rightmost child, which is adjacent to 'node'. - * - * @param node - * @return - */ - public Node getPreviousLeafNeighbor(Node node) { - return getLastLeafChild(getPreviousNeighbor(node)); - } - - /** - * Get next sibling, or if sibling is null get next neighbor. - * - * @param node - * @return - */ - public Node getNextNeighbor(Node node) { - if (!EditValidateUtil.validNode(node)) { - return null; - } - - while (node != null && node.getNodeType() != Node.DOCUMENT_NODE - && node.getNextSibling() == null) { - node = node.getParentNode(); - } - return (node != null && node.getNodeType() != Node.DOCUMENT_NODE) ? node - .getNextSibling() - : null; - } - - /** - * Get next sibling, or if sibling is null get next neighbor's leftmost leaf - * child which will be adjacent to 'node'. - * - * @param node - * @return - */ - public Node getNextLeafNeighbor(Node node) { - return getFirstLeafChild(getNextNeighbor(node)); - } - - /** - * Get node's rightmost leaf child. - * - * @param node - * @return - */ - private Node getLastLeafChild(Node node) { - if (node == null) { - return null; - } - if (node.getLastChild() != null) { - return getLastLeafChild(node.getLastChild()); - } - return node; - } - - /** - * Get node's leftmost leaf child. - * - * @param node - * @return - */ - protected Node getFirstLeafChild(Node node) { - if (node == null) { - return null; - } - - if (node.getFirstChild() != null) { - return getFirstLeafChild(node.getFirstChild()); - } - return node; - } - - /** - * To see if node is within a indexed region that is started from 'start', - * ended at 'end' - */ - public static boolean within(int start, int end, Node theNode) { - return getNodeStartIndex(theNode) >= start - && getNodeEndIndex(theNode) <= end; - } - - /** - * To see whether the 'position' is within indexed location (start, end) - * - * @param start - * @param end - * @param position - * @return - */ - public boolean within(int start, int end, IDOMPosition position) { - int pos = getIndexedRegionLocation(position); - return start <= pos && pos <= end; - } - - /** - * To see whether the 'theNode' is not within indexed region (start, end) - * - * @param start - * @param end - * @param theNode - * @return - */ - public static boolean outOf(int start, int end, Node theNode) { - if (getNodeLenth(theNode) > 0) { - return getNodeStartIndex(theNode) >= end - || getNodeEndIndex(theNode) <= start; - } - return !((getNodeStartIndex(theNode) >= start && getNodeEndIndex(theNode) <= end)); - } - - /** - * Determine whether the position is at node's edge. When the offset is at - * edge, it is in the leftmost or rightmost offset of node's region. - * - * @param node - * @param offset - * @param direction - * @return - */ - public boolean atEdge(IDOMPosition position, boolean forward) { - Node node = position.getContainerNode(); - int offset = position.getOffset(); - if (forward) { - if (EditModelQuery.isText(node)) { - return offset == node.getNodeValue().length(); - } - return offset == node.getChildNodes().getLength(); - } - return offset == 0; - } - - /** - * Get node's neighbor on the node tree, if forward, then get next, - * otherwise go backward. - * - * @param node - * @param forward - * @return - */ - public Node getNeighbor(Node node, boolean forward) { - if (forward) { - return getNextNeighbor(node); - } - return getPreviousNeighbor(node); - } - - /** - * Get neighbor which is descendent of root. - * - * @param node - * @param root - * @return - */ - public Node getPreviousNeighbor(Node node, Node root) { - if (!EditValidateUtil.validNode(node)) { - return null; - } - while (node != null && node != root - && node.getNodeType() != Node.DOCUMENT_NODE - && node.getPreviousSibling() == null) { - node = node.getParentNode(); - } - return (node != null && node != root && node.getNodeType() != Node.DOCUMENT_NODE) ? node - .getPreviousSibling() - : null; - } - - /** - * Get neighbor which is descendent of root. - * - * @param node - * @param root - * @return - */ - public Node getNextNeighbor(Node node, Node root) { - if (!EditValidateUtil.validNode(node)) { - return null; - } - - while (node != null && node != root - && node.getNodeType() != Node.DOCUMENT_NODE - && node.getNextSibling() == null) { - node = node.getParentNode(); - } - return (node != null && node != root && node.getNodeType() != Node.DOCUMENT_NODE) ? node - .getNextSibling() - : null; - } - - /** - * Get neighbor which is descendent of root. - * - * @param node - * @param forward - * @param root - * @return - */ - public Node getNeighbor(Node node, boolean forward, Node root) { - Assert.isTrue(root != null); - if (forward) { - return getNextNeighbor(node, root); - } - return getPreviousNeighbor(node, root); - } - - /** - * Get node's leaf child which is adjacent to 'node', according to - * 'forward', it will search backward or forward. - * - * @param node - * @param forward - * @return - */ - public Node getLeafNeighbor(Node node, boolean forward) { - if (node == null) { - return null; - } - if (forward) { - return getNextLeafNeighbor(node); - } - return getPreviousLeafNeighbor(node); - } - - /** - * Get neighbor's leaf child, which is adjacent to 'node' - * - * @param node - * @param childIndex - * @param forward - * @return - */ - public Node getLeafNeighbor(Node node, int childIndex, boolean forward) { - if (node == null) { - return null; - } - Node neighbor = getNeighbor(node, childIndex, forward); - if (neighbor != null) { - if (forward) { - return getFirstLeafChild(neighbor); - } - return getLastLeafChild(neighbor); - } - return null; - } - - /** - * First try sibling, if it retruns null, try search neighbor. - * - * @param parent - * @param childIndex - * @param forward - * @return - */ - public Node getNeighbor(Node parent, int childIndex, boolean forward) { - if (!EditValidateUtil.validNode(parent)) { - return null; - } - - NodeList nodeList = parent.getChildNodes(); - if (nodeList != null && nodeList.getLength() > 0) { - if (nodeList.getLength() < childIndex) { - return null; - } - Node childNode = null; - if (!forward) { - --childIndex; - } - childNode = nodeList.item(childIndex); - if (childNode != null) { - return childNode; - } - return getNeighbor(parent, forward); - } - if (parent.getNodeType() == Node.TEXT_NODE) { - return getNeighbor(parent, forward); - } - return null; - } - - /** - * To see whether the textSelection start and end are on the same. - * - * @param model - * @param textSelection - * @param lookForChildren - * @return - */ - public static boolean isSame(IStructuredModel model, - TextSelection textSelection) { - if (model != null && textSelection != null) { - int t1 = textSelection.getOffset(); - int t2 = textSelection.getLength() + t1; - return model.getIndexedRegion(t1) == model.getIndexedRegion(t2); - } - return false; - } - - /** - * To see if the range and text selection covered the same range. - * - * @param model - * @param range - * @param textSelection - * @return - */ - public static boolean isSame(IStructuredModel model, DesignRange range, - TextSelection textSelection) { - if (model != null && range != null && textSelection != null) { - int t1 = textSelection.getOffset(); - int t2 = textSelection.getLength() + t1; - int r1 = getIndexedRegionLocation(DOMRangeHelper.toDOMRange(range) - .getStartPosition()); - int r2 = getIndexedRegionLocation(DOMRangeHelper.toDOMRange(range) - .getEndPosition()); - return (model.getIndexedRegion(t1) == model.getIndexedRegion(r1) && // - model.getIndexedRegion(t2) == model.getIndexedRegion(r2)) - || (model.getIndexedRegion(t2) == model - .getIndexedRegion(r1) && // - model.getIndexedRegion(t1) == model.getIndexedRegion(r2)); - } - return false; - } - - /** - * To see whether the selection is single point. - * - * @param model - * @param textSelection - * @return - */ - public static boolean isSamePoint(TextSelection textSelection) { - return textSelection.getLength() == 0; - } - - /** - * To see whether two IDOMPosition are pointed to a same location. - * - * @param p1 - * @param p2 - * @return - */ - public static boolean isSame(IDOMPosition p1, IDOMPosition p2) { - if (p1 == p2 - || (p1.getContainerNode() == p2.getContainerNode() && p1 - .getOffset() == p2.getOffset())) { - return true; - } - return false; - } - - /** - * To see whether the range's start and end position are pointed to a same - * location. - * - * @param range - * @return - */ - public static boolean isSame(DOMRange range) { - EditValidateUtil.validRange(range); - return isSame(range.getStartPosition(), range.getEndPosition()); - } - - public static boolean isSame(DesignRange range) { - return isSame(range.getStartPosition(), range.getEndPosition()); - } - - public static boolean isSame(DesignPosition p1, DesignPosition p2) { - if (p1 == p2) { - return true; - } - if (p1.getContainerNode() == p2.getContainerNode() - && p1.getOffset() == p2.getOffset()) { - return true; - } - return false; - } - - public boolean isWithinSameText(IDOMPosition p1, IDOMPosition p2) { - if (p1 == null || p2 == null) { - return false; - } - return p1.isText() && p2.isText() - && p1.getContainerNode() == p2.getContainerNode(); - } - - /** - * Get the node absolute start location in its residing IStructuredModel. - * - * @param p - * @return - */ - public static int getIndexedRegionLocation(IDOMPosition p) { - if (!EditValidateUtil.validPosition(p)) { - return -1; - } - Node parent = p.getContainerNode(); - if (p.isText()) { - return ((IndexedRegion) parent).getStartOffset() + p.getOffset(); - } - int index = p.getOffset(); - if (!parent.hasChildNodes()) { - // Element: - if (!isDocument(parent)) { - IStructuredDocumentRegion region = ((IDOMNode) parent) - .getStartStructuredDocumentRegion(); - return region.getEnd(); - } - // Document node: - int offset = ((IndexedRegion) parent).getStartOffset(); - return offset; - } - NodeList children = parent.getChildNodes(); - // After rightmost child - if (children.getLength() == index) { - if (!isDocument(parent)) { - int pos = getNodeEndNameStartIndex(parent); - return pos; - } - int offset = ((IndexedRegion) parent).getEndOffset(); - return offset; - } - Node node = children.item(index); - return ((IndexedRegion) node).getStartOffset(); - } - - /** - * To determine whether the position is at the edge of a node. TODO: temp - * func for later combination - * - * @param node - * @param position - * @return - */ - public boolean isLinked(IDOMPosition nodePos, IDOMPosition position, - boolean left) { - int index = getIndexedRegionLocation(position); - if (left) { - int pos = getIndexedRegionLocation(nodePos); - return pos == index; - } - Node node = null; - int end; - if (nodePos.isText()) { - node = nodePos.getContainerNode(); - end = ((IndexedRegion) node).getEndOffset(); - } else { - node = nodePos.getNextSiblingNode(); - Assert.isTrue(node != null); - end = ((IndexedRegion) node).getEndOffset(); - } - return end == index; - } - - /** - * To see if the location is at the node's indexed pos, posType can be - * START_INDEX_BEFORE_TAG, END_INDEX_WITHIN_TAG When location is at these - * two position, webtools returns the container tag name, so we need to know - * these. - * - * @param location - * @param node - * @return - */ - public boolean isAtNodeNameEdge(int location, Node node, int posType) { - int start = getNodeEndNameStartIndex(node); - return location == start; - } - - public boolean isAtNodeNameEdge(int location, Node node) { - return isAtNodeNameEdge(location, node, START_INDEX_BEFORE_TAG) - || isAtNodeNameEdge(location, node, END_INDEX_WITHIN_TAG); - } - - /** - * If text only contains chars '\r' or '\n', it is considered to be - * transparent. - * - * @param node - * @return - */ - public static boolean isTransparentText(Node node) { - // should valid non null? - Assert.isTrue(node != null); - if (node == null || !isText(node)) { - return false; - } - if (!EditValidateUtil.validText(node)) { - return false; - } - - Text text = (Text) node; - if (text.getLength() == 0) { - return true; - } - String value = text.getNodeValue(); - int i = 0; - while (i < value.length() && HTMLUtil.isHTMLWhitespace(value.charAt(i))) { - i++; - } - return i == value.length(); - } - - /** - * Get node index in its parent's children. - * - * @param node - * @return - */ - public static int getNodeIndex(Node node) { - EditValidateUtil.validNode(node); - Node parent = node.getParentNode(); - int index = 0; - for (Node child = parent.getFirstChild(); child != null; child = child - .getNextSibling()) { - if (child == node) { - return index; - } - index++; - } - return -1; // error - } - - /** - * If parent has more than one children of which each node's localName is - * the same as of 'node', return the index of 'node' in the same type - * children list. - * - * @param node - * @return - */ - public int getSameTypeNodeIndex(Node node) { - EditValidateUtil.validNode(node); - int i = 0; - while (node != null) { - Node sibling = node.getPreviousSibling(); - if (sibling != null && sibling.getLocalName() != null - && sibling.getLocalName().equals(node.getLocalName())) { - i++; - } - node = sibling; - } - return i; // error - } - - /** - * Start from position, skip transparent chars, and returns the first - * non-transparent char's index. based on 'forward', go previously or next . - * - * @param value - * @param position - * @param forward - * @return - */ - public int getNextConcretePosition(String value, int position, - boolean forward) { - if (value == null) { - return -1; - } - if (value.length() == 0) { - return 0; - } - // validate - Assert.isTrue(position >= 0 && position <= value.length()); - int i = -1; - if (forward) { - i = position; - while (i < value.length() - && (value.charAt(i) == SWT.CR || value.charAt(i) == SWT.LF)) { - i++; - } - return i; - } - i = position - 1; - while (i >= 0 - && (value.charAt(i) == SWT.CR || value.charAt(i) == SWT.LF)) { - i--; - } - return i + 1; - } - - /** - * Get two nodes' lowest common ancestor. - * - * @param node1 - * @param node2 - * @return - */ - public Node getCommonAncestor(Node node1, Node node2) { - if (node1 == null || node2 == null) { - return null; - } - - for (Node na = node1; na != null; na = na.getParentNode()) { - for (Node ta = node2; ta != null; ta = ta.getParentNode()) { - if (ta == na) - return ta; - } - } - return null; // not found - } - - /** - * Get lowest common ancestor of two IDOMPositions' container nodes.. - * - * @param p1 - * @param p2 - * @return - */ - public Node getCommonAncestor(IDOMPosition p1, IDOMPosition p2) { - Node n1 = p1.getContainerNode(); - Node n2 = p2.getContainerNode(); - return getCommonAncestor(n1, n2); - } - - /** - * Get lowest ancestor of a 'node' which is block type. - * - * @param node - * @return - */ - public Node getBlockAncestor(Node node) { - if (!EditValidateUtil.validNode(node)) { - return null; - } - while (node != null && isChild(IHTMLConstants.TAG_BODY, node, true)) { - if (isBlockNode(node)) { - return node; - } - node = node.getParentNode(); - } - return null; - } - - /** - * To see whether a node is block type. - * - * @param node - * @return - */ - public static boolean isBlockNode(Node node) { - return !isInline(node); - } - - public static boolean isTableCell(Node node) { - if (node instanceof INodeNotifier) { - Object adapter = ((INodeNotifier) node) - .getAdapterFor(ICSSStyle.class); - if (adapter != null) { - ICSSStyle style = (ICSSStyle) adapter; - String display = style.getDisplay(); - return display.equalsIgnoreCase(ICSSPropertyID.VAL_TABLE_CELL); - } - } - return false; - } - - /** - * To see if a node's display type is inline. - * - * @param node - * @return - */ - public static boolean isInline(Node refNode) { - Node node = refNode; - EditPart part = Target.resolvePart(node); - if (part instanceof ElementEditPart) { - node = ((ElementEditPart) part).getTagConvert().getResultElement(); - } - if (isText(node)) { - return true; - } else if (node instanceof INodeNotifier) { - Object adapter = ((INodeNotifier) node) - .getAdapterFor(ICSSStyle.class); - if (adapter != null) { - ICSSStyle style = (ICSSStyle) adapter; - String display = style.getDisplay(); - return (display.equalsIgnoreCase(ICSSPropertyID.VAL_INLINE) - || // - display - .equalsIgnoreCase(ICSSPropertyID.VAL_INLINE_TABLE) - || // - display.equalsIgnoreCase(ICSSPropertyID.VAL_COMPACT) || // - display.equalsIgnoreCase(ICSSPropertyID.VAL_RUN_IN)); - } - } - return false; - } - - public static boolean isListItem(Node node) { - if (node instanceof INodeNotifier) { - Object adapter = ((INodeNotifier) node) - .getAdapterFor(ICSSStyle.class); - if (adapter != null) { - ICSSStyle style = (ICSSStyle) adapter; - String display = style.getDisplay(); - return (display.equalsIgnoreCase(ICSSPropertyID.VAL_LIST_ITEM)); - } - } - return false; - } - - /** - * The net effect of this method is that (subject to flags), true - * is returned if 'node' is the descendant (not really a child) - * of a tag with a local name in the list of 'names'. - * - * TODO C.B: I hate method. Need to rename and possibly rewrite - * - * @param names -- check this list for valid local names - * @param node -- the node to check - * @param ignoreCase -- if true, each node name has toLowerCase applied to - * it before checking for it names. NOTE: this assumes that names is already - * in lowercase. TODO: this is crappy assumption - * @param noSame -- if true, then node is skipped and only its parent nodes are - * checked - * @return true if the local name of node or one of its parents - * is in the array of Strings called names. - */ - public static boolean isChild(final String names[], Node node, - boolean ignoreCase, boolean noSame) { - if (node == null) { - return false; - } - if (noSame) { - node = node.getParentNode(); - } - - final List namesAsList = Arrays.asList(names); - - while (node != null && !isDocument(node)) { - String nodeName = node.getLocalName(); - - if (nodeName != null) - { - if (ignoreCase) - { - nodeName = nodeName.toLowerCase(); - } - - if (namesAsList.contains(nodeName)) - { - return true; - } - } - Node oldNode = node; - node = node.getParentNode(); - if (oldNode == node) - { - throw new IllegalStateException("Infinite loop discovered in DOM tree"); - } - } - return false; - } - - /** - * Determine whether a node is a child of node that is named as 'name', if - * the node itself is named as 'name' return true also. - * - * @param name - * @param node - * @return - */ - public static boolean isChild(String name, Node node, boolean ignoreCase) { - if (node == null) { - return false; - } - - while (node != null && node.getNodeType() != Node.DOCUMENT_NODE) { - String nodeName = node.getLocalName(); - if (nodeName != null - && (ignoreCase && name.equalsIgnoreCase(nodeName) || !ignoreCase - && name.equalsIgnoreCase(nodeName))) { - return true; - } - node = node.getParentNode(); - } - return false; - } - - /** - * To see whether 'node' is 'ancestor's child. - * - * @param ancestor - * @param node - * @return - */ - public static boolean isChild(Node ancestor, Node node) { - if (node == null || ancestor == null) { - return false; - } - - if (isDocument(ancestor)) { - return true; - } - while (node != null && !isDocument(ancestor)) { - if (node == null) { - break; - } - if (node == ancestor) { - return true; - } - node = node.getParentNode(); - } - return false; - } - - /** - * Get next sibling node to position's container node. - * - * @param position - * @return - */ - public Node getNextSibling(IDOMPosition position) { - if (position.isText()) { - return position.getContainerNode().getNextSibling(); - } - return position.getNextSiblingNode(); - } - - /** - * Get previous sibling node to position's container node. - * - * @param position - * @return - */ - public Node getPreviousSibling(IDOMPosition position) { - if (position.isText()) { - return position.getContainerNode().getPreviousSibling(); - } - return position.getPreviousSiblingNode(); - } - - /** - * Get position's container node's parent. - * - * @param position - * @return - */ - public Node getParent(IDOMPosition position) { - if (position.isText()) { - return position.getContainerNode().getParentNode(); - } - return position.getContainerNode(); - } - - /** - * Get node's sibling according to 'forward' direction - * - * @param node - * @param forward - * @return - */ - public Node getSibling(Node node, boolean forward) { - EditValidateUtil.validNode(node); - if (forward) { - return node.getNextSibling(); - } - return node.getPreviousSibling(); - } - - /** - * Get position's container node's sibling. - * - * @param position - * @param forward - * @return - */ - public Node getSibling(IDOMPosition position, boolean forward) { - if (forward) { - return getNextSibling(position); - } - return getPreviousSibling(position); - } - - /** - * Get position's container node's editable items number. this is temp - * functions for future use. - * - * @param position - * @return - */ - public int getSize(IDOMPosition position) { - EditValidateUtil.validPosition(position); - if (position.isText()) { - return ((Text) position.getContainerNode()).getLength(); - } - if (position.getContainerNode().hasChildNodes()) { - return position.getContainerNode().getChildNodes().getLength(); - } - return 0; - } - - /** - * Valid position and return text, if it contains text node. - * - * @param position - * @return - */ - public Text getText(IDOMPosition position) { - if (position.isText()) { - if (position.getContainerNode() != null) { - return (Text) position.getContainerNode(); - } - } - return null; - } - - public static Document getDocumentNode(Node node) { - if (node != null) { - return isDocument(node) ? (Document) node : node.getOwnerDocument(); - } - return null; - } - - /** - * To see whether a node is empty, here we can insert rules to see whether - * it is empty, for delete operation, it could be deleted. - * - * @param node - * @return - */ - public static boolean isEmptyNode(Node node) { - if (node.getNodeType() == Node.TEXT_NODE) { - return isTransparentText(node); - } - if (node.getChildNodes() == null - || node.getChildNodes().getLength() == 0) { - return true; - } - return false; - } - - /** - * To see whther a node is text node. - * - * @param node - * @return - */ - public static boolean isText(Node node) { - return node != null && node.getNodeType() == Node.TEXT_NODE; - } - - /** - * To see whether a node is Document node. - * - * @param node - * @return - */ - public static boolean isDocument(Node node) { - return node != null && node.getNodeType() == Node.DOCUMENT_NODE; - } - - // TODO: dead? -// private static boolean isHead(Node node) { -// return node.getNodeName().equalsIgnoreCase(IHTMLConstants.TAG_HEAD); -// } - - /** - * Get style from parent node. from first paret 'firstF', we will traverse - * the tree up untile reaching Document node, get all style node's, we may - * insert rules here to stop the search at a before paricular node. Style - * nodes could <b>, <u>... - * - * @param children - * @param firstF - * @return - */ - public void assignFather(Vector children, Node firstF) { - if (children.size() == 0) { - return; - } - if (firstF != null && !isDocument(firstF)) { - String name = firstF.getNodeName(); - // To see whether it is a style node that is our anticipated node. - if (name != null && HTML_STYLE_NODES.contains(name.toLowerCase())) { - Node newParent = firstF.cloneNode(false); - while (children.size() > 0) { - newParent.appendChild((Node) children.remove(0)); - } - children.add(newParent); - } - assignFather(children, firstF.getParentNode()); - } - } - - /** - * Get a node that is at Indexed position 'pos' in 'model'. - * - * @param model - * @param pos - * @return - */ - public Object getPosNode(IStructuredModel model, int pos) { - IndexedRegion inode = model.getIndexedRegion(pos); - return inode; - } - - /** - * If the pos is at right edge within container. - * - * @param model - * @param pos - * @return - */ - public boolean isAtRightMostWithin(Node node, int pos) { - return getNodeEndNameStartIndex(node) == pos; - } - - /** - * Create the node, if 'refNode' is null, then position is at the edge of - * 'container'. otherwize calculate refNode's related index in its parent's - * children list and return DOMPosition. - * - * @param container - * @param refNode - * @param forward - * @return - */ - public IDOMPosition createDomposition(Node container, Node refNode, - boolean forward) { - if (refNode == null) { - if (forward && container.hasChildNodes()) { - return new DOMPosition(container, container.getChildNodes() - .getLength()); - } - return new DOMPosition(container, 0); - } - Assert.isTrue(refNode.getParentNode() == container); - int index = getNodeIndex(refNode); - if (!forward) { - index++; - } - return new DOMPosition(container, index); - } - - public static DesignRange convertToDesignRange(IStructuredModel fModel, - TextSelection textSelection) { - int start = textSelection.getOffset(); - int end = textSelection.getLength() + start; - IDOMPosition startDomPos = EditModelQuery.getInstance() - .createDomposition((IDOMModel) fModel, start, false); - IDOMPosition endDomPos = EditModelQuery.getInstance() - .createDomposition((IDOMModel) fModel, end, false); - if (startDomPos == null) { - startDomPos = endDomPos; - } else if (endDomPos == null) { - endDomPos = startDomPos; - } - if (startDomPos != null) { - DesignPosition startPos = null, endPos = null; - startPos = DOMPositionHelper.toDesignPosition(startDomPos); - endPos = DOMPositionHelper.toDesignPosition(endDomPos); - if (startPos != null) { - return new DesignRange(startPos, endPos); - } - } - return null; - } - - /** - * Create IDOMPosition based on Indexed 'position' in model. If node at - * position is text, use position to calculate DOMPosition offset, - * otherwize, simply create position pointed to container's children list's - * edge. - * - * @param container - * @param position - * @return - */ - public IDOMPosition createDomposition(IDOMModel model, int position, - boolean adjust) { - return createDomposition1(model, position, adjust); - } - - /** - * Create IDOMPosition based on Indexed 'position' in model. If node at - * position is text, use position to calculate DOMPosition offset, - * otherwize, simply create position pointed to container's children list's - * edge. - * - * @param container - * @param position - * @return - */ - public IDOMPosition createDomposition1(IDOMModel model, int position, - boolean adjust) { - try { - // TODO: never read -// IMovementMediator validator = new InlineEditingNavigationMediator( -// new ActionData(ActionData.INLINE_EDIT, null)); - // get the container - Object object = getPosNode(model, position); - if (object == null && position > 0) { - // The end of file? - object = getPosNode(model, position - 1); - } - Node container = null; - if (object == null) { - // empty file? - return new DOMPosition(model.getDocument(), 0); - } - container = (Node) object; - Object oppNode = getPosNode(model, position - 1); - if (oppNode != null - && !EditModelQuery.isChild((Node) oppNode, container) - && // - !EditModelQuery.isInline(container) - && EditModelQuery.isInline((Node) oppNode)) { - container = (Node) oppNode; - } - int location = EditHelper.getInstance().getLocation(container, - position, false); - IDOMPosition result = null; - switch (location) { - case 1: - case 2: - result = new DOMRefPosition(container, false); - break; - case 4: - case 5: - result = new DOMRefPosition(container, true); - break; - case 3: - if (EditModelQuery.isText(container)) { - result = new DOMPosition(container, position - - EditModelQuery.getNodeStartIndex(container)); - } else { - result = new DOMPosition(container, container - .getChildNodes().getLength()); - } - } - return result; - } catch (Exception e) { - // "Error in position creation" - _log.error("Error.EditModelQuery.0" + e); //$NON-NLS-1$ - return null; - } - } - - /** - * Calculate node's Indexed length in model. - * - * @param node - * @return - */ - public static int getNodeLenth(Node node) { - if (node != null - && EditValidateUtil.validNode(node)) { - return ((IndexedRegion) node).getEndOffset() - - ((IndexedRegion) node).getStartOffset(); - } - return 0; - } - - /** - * Return 'node' indexed start position Example: |<a></a>, the position is - * indicated by '|' - * - * @param node - * @return - */ - public static int getNodeStartIndex(Node node) { - if (EditValidateUtil.validNode(node) && node instanceof IndexedRegion) { - return ((IndexedRegion) node).getStartOffset(); - } - return -1; - } - - /** - * Return 'node' indexed end position Example: <a></a>|, the position is - * indicated by '|' - * - * @param node - * @return - */ - public static int getNodeEndIndex(Node node) { - if (EditValidateUtil.validNode(node) && node instanceof IndexedRegion) { - return ((IndexedRegion) node).getEndOffset(); - } - return -1; - } - - /** - * Get node at indexed position. - * - * @param position - * @return - */ - public static Node getNodeAt(IStructuredModel model, int position) { - try { - IndexedRegion region = model.getIndexedRegion(position); - if (region instanceof Node) { - return (Node) region; - } - return null; - } catch (Exception e) { - // "Error in region node creation" - _log.error("Error.EditModelQuery.1", e); //$NON-NLS-1$ - return null; - } - } - - /** - * Return 'node' indexed start name's end position Example: <a>|aaa </a>, - * the position is indicated by '|' - * - * @param node - * @return - */ - public static int getNodeStartNameEndIndex(Node node) { - if (isText(node)) { - return getNodeStartIndex(node); - } - if (EditValidateUtil.validNode(node) && node instanceof IDOMNode) { - IStructuredDocumentRegion region = ((IDOMNode) node) - .getStartStructuredDocumentRegion(); - if (region != null) { - return region.getEndOffset(); - } - // else - // { - // // if (node.hasChildNodes()) - // // { - // // // Node should always have start name, so this part should - // never reach, - // // // the assert is for inner debug. - // // Assert.isTrue(false); - // // return getNodeStartIndex(node); - // // } - // } - } - // This should never happen. - return getNodeStartIndex(node); - } - - /** - * Return 'node' indexed end name' start position Example: <a>aaa| </a>, the - * position is indicated by '|' If node is <a /> style or there is no </a> - * to pair with <a>, the function return -1. - * - * @param node - * @return - */ - public static int getNodeEndNameStartIndex(Node node) { - if (isText(node)) { - return getNodeEndIndex(node); - } - if (EditValidateUtil.validNode(node) && node instanceof IDOMNode) { - IStructuredDocumentRegion region = ((IDOMNode) node) - .getEndStructuredDocumentRegion(); - if (region != null) { - return region.getStartOffset(); - } - // else - // { - // if (node.hasChildNodes()) - // { - // return getNodeEndIndex(node); - // } - // } - } - return getNodeEndIndex(node); - } - - /** - * To see if a node is <a/>style. - * - * @param node - * @return - */ - public boolean isSingleRegionNode(Node node) { - if (getNodeEndNameStartIndex(node) == getNodeEndIndex(node) - && !node.hasChildNodes()) { - return true; - } - return false; - } - - /** - * To see if a node has child that is not transparent child only. - * - * @param node - * @return - */ - public boolean hasNonTransparentChild(Node node) { - NodeList children = node.getChildNodes(); - for (int i = 0, n = children.getLength(); i < n; i++) { - Object child = children.item(i); - if (isText((Node) child)) { - if (!isTransparentText((Node) child)) { - return true; - } - } else { - return true; - } - } - return false; - } - - /** - * To see if a node has child that is not transparent child only. - * - * @param node - * @return - */ - public boolean hasNonTransparentChild(Node node, String[] excludes) { - if (!node.hasChildNodes()) { - return false; - } - NodeList children = node.getChildNodes(); - for (int i = 0, n = children.getLength(); i < n; i++) { - Object child = children.item(i); - if (isText((Node) child)) { - if (!isTransparentText((Node) child)) { - return true; - } - } else if (!Arrays.asList(excludes).contains( - ((Node) child).getLocalName())) { - return true; - } - } - return false; - } - - /** - * To see whether tag has whitespace char. - * - * @param node - * @return - */ - public boolean hasWhitespaceNeighbor(Node node) { - node = getNeighbor(node, true); - if (isWidget(node)) { - return false; - } - node = getFirstLeafChild(node); - return isTransparentText(node); - - } - - /** - * @param host - * @return - */ - public static boolean isWidget(Object host) { - boolean result = false; - EditPart part = null; - if (host instanceof EditPart) { - part = (EditPart) host; - } else if (host instanceof Node) { - part = Target.resolvePart((Node) host); - if (part == null) { - part = new HTMLEditPartsFactory( - (IDOMDocument) getDocumentNode((Node) host)) - .createEditPart(null, host); - } - } - if (part instanceof NodeEditPart) { - result = ((NodeEditPart) part).isWidget(); - } - return result; - } - - /** - * To combind whitespace chars, only one whitespace string should be create. - * - * @param node - * @return - */ - public boolean isRedundantWightspaces(Node node) { - if (isTransparentText(node) && hasWhitespaceNeighbor(node)) { - return true; - } - return false; - } - - public static boolean hasAncestor(Node node, String names[], - boolean ignoreCase) { - Assert.isTrue(names != null); - while (node != null && !EditModelQuery.isDocument(node)) { - if (isElement(node)) - if (containItem(names, node, ignoreCase)) { - return true; - } - node = node.getParentNode(); - } - return false; - } - - /** - * To see if 'node' has ancestor that has name as 'name' - * - * @param node - * @param name - * @param ignoreCase - * @return - */ - public static boolean hasAncestor(Node node, String name, boolean ignoreCase) { - Assert.isTrue(name != null); - while (node != null && !EditModelQuery.isDocument(node)) { - if (node.getNodeName() != null) - if ((ignoreCase && name.equalsIgnoreCase(node.getNodeName())) || // - (!ignoreCase && name.equals(node.getNodeName()))) { - return true; - } - node = node.getParentNode(); - } - return false; - } - - /** - * To see if 'node' has direct ancestors that has names listed in 'name[]' - * - * @param node - * @param name - * @param ignoreCase - * @return - */ - public static List getAncestors(Node node, String top, boolean ignoreCase) { - List result = new ArrayList(); - Assert.isTrue(node != null); - while (node != null && !EditModelQuery.isDocument(node)) { - result.add(node); - String name = node.getLocalName(); - if (ignoreCase && top.equalsIgnoreCase(name) || // - (!ignoreCase && top.equals(name))) { - break; - } - node = node.getParentNode(); - } - return result; - } - - /** - * Copy old node's children to newNode.If the newNode is the father of the - * old node,then the old node's children will be inserted before the old - * node,otherwise,the old node's children just append to the newNode. - * - * @param old - * @param newNode - * @return - */ - public static void copyChildren(Node old, Node newNode) { - Node child = old.getFirstChild(); - while (child != null) { - Node next = child.getNextSibling(); - child = old.removeChild(child); - if (old.getParentNode() == newNode) { - newNode.insertBefore(child, old); - } else { - newNode.appendChild(child); - } - child = next; - } - } - - public static boolean isElement(Node node) { - return node.getNodeType() == Node.ELEMENT_NODE; - } - - /** - * Return a offspring of ancestor, the offsprint has a name listed in - * childrenNames. - * - * @param ancestor - * @param childrenNames - * @param maxLevelToSearch: - * the max level from ancestor to the offspring in family tree. - * @param ignoreCase - * @return - */ - public static Node getChild(Node ancestor, String childrenNames[], - int maxLevelToSearch, boolean ignoreCase) { - if (ancestor == null || maxLevelToSearch < 0) { - return null; - } - if (ancestor.getLocalName() != null - && ignoreCase - && Arrays.asList(childrenNames).contains( - ancestor.getLocalName().toLowerCase()) - || !ignoreCase - && Arrays.asList(childrenNames).contains( - ancestor.getLocalName())) { - return ancestor; - } - NodeList children = ancestor.getChildNodes(); - for (int i = 0, n = children.getLength(); i < n; i++) { - Node result = getChild(children.item(i), childrenNames, - maxLevelToSearch - 1, ignoreCase); - if (result != null) { - return result; - } - } - return null; - } - - /** - * Return a offspring of ancestor, the nodes on the tree are type of - * DeferredElementImpl, the offsprint has a name listed in childrenNames. - * - * @param ancestor - * @param childrenNames - * @param maxLevelToSearch: - * the max level from ancestor to the offspring in family tree. - * @param ignoreCase - * @return - */ - public static Node getChildDeferredNode(Node ancestor, - String childrenNames[], int maxLevelToSearch, boolean ignoreCase) { - if (ancestor == null || maxLevelToSearch < 0) { - return null; - } - String nodeName = ancestor.getNodeName(); - if (nodeName != null && ignoreCase - && Arrays.asList(childrenNames).contains(nodeName) - || !ignoreCase - && Arrays.asList(childrenNames).contains(nodeName)) { - return ancestor; - } - NodeList children = ancestor.getChildNodes(); - for (int i = 0, n = children.getLength(); i < n; i++) { - Node result = getChildDeferredNode(children.item(i), childrenNames, - maxLevelToSearch - 1, ignoreCase); - if (result != null) { - return result; - } - } - return null; - } - - public static boolean hasTransparentNodeOnly(Node node) { - NodeList children = node.getChildNodes(); - for (int i = 0, n = children.getLength(); i < n; i++) { - if (!EditModelQuery.isTransparentText(children.item(i))) { - return false; - } - } - return true; - } - - public static Node getParent(String name, Node node, boolean ignoreCase) { - if (node == null) { - return null; - } - - while (node != null && node.getNodeType() != Node.DOCUMENT_NODE) { - String nodeName = node.getLocalName(); - if (nodeName != null - && (ignoreCase && name.equalsIgnoreCase(nodeName) || !ignoreCase - && name.equalsIgnoreCase(nodeName))) { - return node; - } - node = node.getParentNode(); - } - return null; - } - - /** - * get Elements with the same localName as the input localName under the - * rootNode,it is a recursive computation. - * - * @param rootNode - * @param localName - * @param caseSensitive - * @param list - * The input list to hold the matched elements. - */ - public static void getElementByLocalName(Node rootNode, String localName, - boolean caseSensitive, List list) { - if (list == null) { - return; - } - NodeList nodeList = rootNode.getChildNodes(); - if (nodeList != null && nodeList.getLength() > 0) { - for (int i = 0, size = nodeList.getLength(); i < size; i++) { - Node node = nodeList.item(i); - if (node.getNodeType() == Node.ELEMENT_NODE) { - String nodeLocalName = node.getLocalName(); - if (caseSensitive && localName.equals(nodeLocalName)) { - list.add(node); - } else if (!caseSensitive - && localName.equalsIgnoreCase(nodeLocalName)) { - list.add(node); - } - getElementByLocalName(node, localName, true, list); - } - - } - } - } - - public static boolean containItem(String[] tags, Node node, - boolean ignoreCase) { - if (ignoreCase) { - for (int i = 0, size = tags.length; i < size; i++) { - if (tags[i] == null) { - continue; - } - if (tags[i].equalsIgnoreCase(node.getNodeName())) { - return true; - } - } - } else { - for (int i = 0, size = tags.length; i < size; i++) { - if (tags[i] == null) { - continue; - } - if (tags[i].equals(node.getNodeName())) { - return true; - } - } - } - return false; - } -} |