Package org.eclipse.jst.pagedesigner.dom

Source Code of org.eclipse.jst.pagedesigner.dom.DOMPositionHelper

/*******************************************************************************
* 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.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.gef.EditPart;
import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
import org.eclipse.jst.pagedesigner.parts.TextEditPart;
import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
* @author mengbo
*/
public class DOMPositionHelper {
  /**
   * @param position
   * @return the design position
   */
  public static DesignPosition toDesignRefPosition(DOMRefPosition position) {
    Node node = position.getReferenceNode();
    do {
      IDOMNode container = (IDOMNode) node.getParentNode();
      EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
      if (part != null) {
        // XXX: what if the node has not corresponding part?
        EditPart child = DOMPositionHelper.findEditPart(part, node);
        if (child != null) {
          return new DesignRefPosition(child, position.isForward());
        }
                return DesignPosition.INVALID;
      }
            node = node.getParentNode();
    } while (true);
  }

  /**
   *
   * @param position
   *            if it is null, then will return null
   * @return null if position is null or invalid.
   */
  public static DesignPosition toDesignPosition(IDOMPosition position) {
    if (position == null) {
      return null;
    }
    if (position instanceof DOMRefPosition) {
      return toDesignRefPosition((DOMRefPosition) position);
    }
    do {
      IDOMNode container = (IDOMNode) position.getContainerNode();
      EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
      if (part != null) {
        if (container instanceof Text) {
          String textData = ((Text) container).getData();
          String displayData = ((TextEditPart) part).getTextData();
          return new DesignPosition(part,
              textDataOffsetToDisplayOffset(textData,
                  displayData, position.getOffset()));
        }
                Node pre = position.getPreviousSiblingNode();
                while (pre != null) {
                  int index = findChildEditPartIndex(part, pre);
                  if (index != -1) {
                    return new DesignPosition(part, index + 1);
                  }
                  pre = pre.getPreviousSibling();
                }
                return new DesignPosition(part, 0);
      }
            position = new DOMRefPosition(position.getContainerNode(),
                false);
    } while (true);
  }

  /**
   * Here is the position is not currect, currently it will returns invalid
   * pos.
   *
   * @param position
   * @return the design position
   */
  public static DesignPosition toDesignPosition1(IDOMPosition position) {
    if (position instanceof DOMRefPosition) {
      return toDesignRefPosition((DOMRefPosition) position);
    }
    do {
      IDOMNode container = (IDOMNode) position.getContainerNode();
      EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
      if (part != null) {
        if (container instanceof Text) {
          String textData = ((Text) container).getData();
          String displayData = ((TextEditPart) part).getTextData();
          return new DesignPosition(part,
              textDataOffsetToDisplayOffset(textData,
                  displayData, position.getOffset()));
        }
                Node pre = position.getPreviousSiblingNode();
                while (pre != null) {
                  int index = findChildEditPartIndex(part, pre);
                  if (index != -1) {
                    return new DesignPosition(part, index + 1);
                  }
                  pre = pre.getPreviousSibling();
                }
                return new DesignPosition(part, 0);
      }
            return DesignPosition.INVALID;
    } while (true);
  }

  static int findChildEditPartIndex(EditPart parent, Node node) {
    List children = parent.getChildren();
    for (int i = 0; i < children.size(); i++) {
      if (((EditPart) children.get(i)).getModel() == node) {
        return i;
      }
    }
    return -1;
  }

  static EditPart findEditPart(EditPart parent, Node node) {
    List children = parent.getChildren();
    EditPart part;
    for (int i = 0; i < children.size(); i++) {
      if ((part = (EditPart) children.get(i)).getModel() == node) {
        return part;
      }
    }
    return null;
  }

  /**
   * convert a DesignPosition into DOMPosition.
   *
   * @param position
   * @return the dom position
   */
  public static IDOMPosition toDOMRefPosition(DesignRefPosition position) {
    // ok, it is not text.
    EditPart sibling = position.getRefPart();
    if (sibling != null) {
      return new DOMRefPosition((Node) sibling.getModel(), position
          .caretIsAtRight());
    }
    // should never happens
    Assert.isTrue(false);
    return null;
  }

  /**
   * convert a DesignPosition into DOMPosition.
   *
   * @param position
   * @return the dom position
   */
  public static IDOMPosition toDOMPosition(DesignPosition position) {
    if (!EditValidateUtil.validPosition(position)) {
      return null;
    } else if (position instanceof DesignRefPosition) {
      return toDOMRefPosition((DesignRefPosition) position);
    }
    EditPart part = position.getContainerPart();
    if (part instanceof TextEditPart) {
      Text text = (Text) ((TextEditPart) part).getIDOMNode();
      int offset = position.getOffset();
      if (offset == 0) {
        return new DOMPosition(text, 0);
      }
            String displayData = ((TextEditPart) part).getTextData();
            String nodeData = text.getData();
            if (offset >= displayData.length()) {
              // point to end of the text node.
              return new DOMPosition(text, nodeData.length());
            }
            // we need to calculate it out.
            int index = displayOffsetToTextDataOffset(displayData,
                nodeData, offset);
            return new DOMPosition(text, index);
    }
        // ok, it is not text.
        EditPart sibling = position.getSiblingEditPart(true);
        if (sibling instanceof NodeEditPart) {
          return new DOMRefPosition(((NodeEditPart) sibling).getDOMNode(), false);
        }

        sibling = position.getSiblingEditPart(false);
        if (sibling instanceof NodeEditPart) {
          return new DOMRefPosition(((NodeEditPart) sibling).getDOMNode(), true);
        }

        // no previous sibling, no next sibling, the parent node must be
        // empty
        return new DOMPosition(((NodeEditPart) part).getDOMNode(), 0);
  }

  /**
   * if "position" is inside a text node, then split the text node and return
   * a new IDOMPosition semantically equal to the position in the two
   * splitted text. If the "position" is not a text position, then no action
   * will be taken and will return the original position.
   *
   * @param position
   * @return IDOMPosition
   */
  public static IDOMPosition splitText(IDOMPosition position) {
    Node container = position.getContainerNode();
    if (container instanceof Text) {
      int offset = position.getOffset();
      if (offset <= 0) {
        // at beginning of text node. no need to split
        return new DOMRefPosition(container, false);
      }
      String textData = ((Text) container).getData();
      if (offset >= textData.length()) {
        // at end of text node. no need to split
        return new DOMRefPosition(container, true);
      }
      // ok, we need split
      ((Text) container).splitText(offset);
      return new DOMRefPosition(container, true);
    }
        return position;
  }

  /**
   * Remove all the content in the range. And return the new position.
   *
   * @param range
   * @return the dom position
   */
  public static IDOMPosition removeRange(DOMRange range) {
    boolean ordered = range.isOrdered();
//    IDOMPosition start = ordered ? range.getStartPosition() : range
//        .getEndPosition();
    IDOMPosition end = ordered ? range.getEndPosition() : range
        .getStartPosition();

    // FIXME: Not DONE:
    return end;
  }

  /**
   * try to merge the position in adjacent text node (if it is not already in)
   *
   * @param position
   * @return the dom position
   */
  public static IDOMPosition mergeIntoText(IDOMPosition position) {
    if (position.getContainerNode() instanceof Text)
      return position;
    Node pre = position.getPreviousSiblingNode();
    if (pre instanceof Text) {
      return new DOMPosition(pre, ((Text) pre).getData().length());
    }
    Node after = position.getNextSiblingNode();
    if (after instanceof Text) {
      return new DOMPosition(after, 0);
    }
    return position;
  }

  /**
   * @param displayData
   * @param nodeData
   * @param offset
   * @return the offset
   */
  // FIXME: this method is still buggy
  public static int displayOffsetToTextDataOffset(String displayData,
      String nodeData, int offset) {
    char[] display = displayData.toCharArray();
    if (offset >= display.length) {
      // offset is already at end
      return nodeData.length();
    }
    char[] node = nodeData.toCharArray();
    int nodeDataLength = node.length;
    int displayIndex = 0;
    int nodeIndex = 0;

    while (displayIndex < offset && nodeIndex < nodeDataLength) {
      if (display[displayIndex] == node[nodeIndex]) {
        displayIndex++;
        nodeIndex++;
        continue;
      }
      if (HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
        if (HTMLUtil.isHTMLWhitespace(display[displayIndex])) {
          displayIndex++;
          nodeIndex++;
        } else {
          nodeIndex++;
        }
        continue;
      }
            // should not happen!
            displayIndex++;
            nodeIndex++;
    }

    if (nodeIndex >= nodeDataLength)
      return nodeDataLength;
    // else means displayIndex == offset
    // since we already checked that offset < displayLength, so we can get
    // the next char
    if (display[offset] != ' ') {
      // we may need to skip whitespaces after nodeIndex
      while (nodeIndex < nodeDataLength
          && HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
        nodeIndex++;
      }
    }
    return nodeIndex;
  }

  /**
   * @param nodeData
   * @param displayData
   * @param offset
   * @return the offset
   */
  // FIXME: this method is still buggy
  public static int textDataOffsetToDisplayOffset(String nodeData,
      String displayData, int offset) {
    if (offset >= nodeData.length()) {
      return displayData.length();
    }
    char[] node = nodeData.toCharArray();
    char[] display = displayData.toCharArray();

    int displayIndex = 0;
    int nodeIndex = 0;
    int displayDataLength = display.length;

    while (nodeIndex < offset && displayIndex < displayDataLength) {
      if (display[displayIndex] == node[nodeIndex]) {
        displayIndex++;
        nodeIndex++;
        continue;
      }
      if (HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
        if (HTMLUtil.isHTMLWhitespace(display[displayIndex])) {
          displayIndex++;
          nodeIndex++;
        } else {
          nodeIndex++;
        }
        continue;
      }
            // should not happen!
            displayIndex++;
            nodeIndex++;
    }
    return displayIndex;
  }

  /**
   * Convert a IDOMPosition to IDOMRefPosition. If can't convert to
   * IDOMRefPosition, will return the original one.
   *
   * @param position
   * @return IDOMPosition
   */
  public static IDOMPosition toDOMRefPosition(IDOMPosition position) {
    if (position.isText()) {
      return position; // can't convert Text node.
    }
    if (position instanceof IDOMRefPosition) {
      return position;
    }
    if (position.getNextSiblingNode() != null) {
      return new DOMRefPosition(position.getNextSiblingNode(), false);
    }
    if (position.getPreviousSiblingNode() != null) {
      return new DOMRefPosition(position.getPreviousSiblingNode(), true);
    }
        return new DOMRefPosition2(position.getContainerNode(), true);
  }
}
TOP

Related Classes of org.eclipse.jst.pagedesigner.dom.DOMPositionHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.