blob: f93405c71998015f0011e35a9a039d2c54fd3862 [file] [log] [blame]
/*******************************************************************************
* 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.validation.caret;
import java.util.Arrays;
import java.util.List;
import org.eclipse.gef.EditPart;
import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
import org.w3c.dom.Node;
/**
* This rule constains the operation within a table: 1. The inputing position
* can only be in 'td' 2. Table structure must be valid.
*
* @author mengbo
*/
public class IETablePositionRule extends DefaultPositionRule {
// We will introduce validation based on DtD later, this is not final
// solution.
private final String[] CONTAINER = { IHTMLConstants.TAG_THEAD,
IHTMLConstants.TAG_TBODY, IHTMLConstants.TAG_TFOOT };
/**
* @param actionData
*/
public IETablePositionRule(ActionData actionData) {
super(actionData);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jst.pagedesigner.caret.IPositionRule#hasEditableArea(org.eclipse.jst.pagedesigner.caret.Target)
*/
public boolean hasEditableArea(Target target) {
if (EditModelQuery.isChild(IHTMLConstants.TAG_TABLE, target.getNode(),
true)) {
if (target.getPart() == null) {
return false;
}
Node node = target.getNode();
// The target must be in a valid table structure.
String name = node.getLocalName();
if (node.hasChildNodes()) {
// for constrained container, depends on its children.
if (name != null
&& (IHTMLConstants.TAG_TABLE.equalsIgnoreCase(name) || //
Arrays.asList(CONTAINER).contains(
name.toLowerCase()) || //
IHTMLConstants.TAG_TR.equalsIgnoreCase(name))) {
List children = target.getPart().getChildren();
for (int i = 0, n = children.size(); i < n; i++) {
if (hasEditableArea(new Target((EditPart) children
.get(i)))) {
return true;
}
}
return false;
}
} else {
if (!isEditable(new Target(node))) {
return false;
}
}
}
return super.hasEditableArea(target);
}
/**
* Used to valid the structure of table, later will use dtd to do that.
* @param container
* @return true if the table is valid
*/
public boolean isInValidTable(Node container) {
boolean result = false;
try {
if (EditValidateUtil.validNode(container)) {
if (EditModelQuery.isText(container)) {
container = container.getParentNode();
}
String name = container.getLocalName();
if (EditModelQuery.isChild(IHTMLConstants.TAG_TABLE, container,
true)) {
List ancestors = EditModelQuery.getAncestors(container,
IHTMLConstants.TAG_TABLE, true);
int offset = ancestors.size();
// remove 'table'
Node temp = (Node) ancestors.remove(offset - 1);
if (temp == container) {
return true;
}
offset--;
result = checkValidTrTd(ancestors, container);
if (!result) {
// thead->tr->td
temp = (Node) ancestors.get(offset - 1);
name = temp.getNodeName();
if (Arrays.asList(CONTAINER).contains(
name.toLowerCase())) {
if (temp == container) {
result = true;
} else {
// remove 'thead'
ancestors.remove(offset - 1);
offset--;
result = checkValidTrTd(ancestors, container);
}
}
}
}
}
return result;
} catch (Exception e) {
// The exception means the structure is not a valid table, don't
// need to report.
return false;
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isEditable(org.eclipse.jst.pagedesigner.caret.Target)
*/
public boolean isEditable(Target target) {
if (EditModelQuery.isChild(IHTMLConstants.TAG_TABLE, target.getNode(),
false)) {
if (isInValidTable(target.getNode())) {
List ancestors = EditModelQuery.getAncestors(target.getNode(),
IHTMLConstants.TAG_TABLE, true);
if (ancestors.size() >= 3) {
if (IHTMLConstants.TAG_TH
.equalsIgnoreCase(((Node) ancestors.get(ancestors
.size() - 3)).getNodeName())
|| //
IHTMLConstants.TAG_TD
.equalsIgnoreCase(((Node) ancestors
.get(ancestors.size() - 3))
.getNodeName())) {
return true;
} else if (ancestors.size() >= 4 //
&& (IHTMLConstants.TAG_TH
.equalsIgnoreCase(((Node) ancestors
.get(ancestors.size() - 4))
.getNodeName()) || //
IHTMLConstants.TAG_TD
.equalsIgnoreCase(((Node) ancestors
.get(ancestors.size() - 4))
.getNodeName()))) {
return true;
}
}
}
return false;
}
return super.isEditable(target);
}
private boolean checkValidTrTd(List ancestors, Node node) {
int offset = ancestors.size();
if (IHTMLConstants.TAG_TR.equalsIgnoreCase(((Node) ancestors
.get(offset - 1)).getLocalName())) {
if (ancestors.get(offset - 1) == node) {
return true;
} else if (IHTMLConstants.TAG_TH.equalsIgnoreCase(((Node) ancestors
.get(offset - 2)).getLocalName())
|| //
IHTMLConstants.TAG_TD.equalsIgnoreCase(((Node) ancestors
.get(offset - 2)).getLocalName())) {
return true;
}
}
return false;
}
}