[richfaces-svn-commits] JBoss Rich Faces SVN: r11758 - in trunk/ui/tree/src: main/java/org/richfaces/component and 4 other directories.
richfaces-svn-commits at lists.jboss.org
richfaces-svn-commits at lists.jboss.org
Sun Dec 14 13:07:10 EST 2008
Author: nbelaevski
Date: 2008-12-14 13:07:10 -0500 (Sun, 14 Dec 2008)
New Revision: 11758
Removed:
trunk/ui/tree/src/test/java/org/richfaces/renderkit/TreeRowKeyComparatorTest.java
Modified:
trunk/ui/tree/src/main/config/component/tree.xml
trunk/ui/tree/src/main/java/org/richfaces/component/UITree.java
trunk/ui/tree/src/main/java/org/richfaces/component/events/TreeEvents.java
trunk/ui/tree/src/main/java/org/richfaces/renderkit/TreeRendererBase.java
trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-item.js
trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-selection.js
trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree.js
Log:
https://jira.jboss.org/jira/browse/RF-4196
Modified: trunk/ui/tree/src/main/config/component/tree.xml
===================================================================
--- trunk/ui/tree/src/main/config/component/tree.xml 2008-12-14 18:03:41 UTC (rev 11757)
+++ trunk/ui/tree/src/main/config/component/tree.xml 2008-12-14 18:07:10 UTC (rev 11758)
@@ -303,6 +303,10 @@
<defaultvalue>""</defaultvalue>
</property>
+ <property>
+ <name>ajaxNodeKeys</name>
+ </property>
+
<property hidden="true">
<name>rowKeyConverter</name>
</property>
Modified: trunk/ui/tree/src/main/java/org/richfaces/component/UITree.java
===================================================================
--- trunk/ui/tree/src/main/java/org/richfaces/component/UITree.java 2008-12-14 18:03:41 UTC (rev 11757)
+++ trunk/ui/tree/src/main/java/org/richfaces/component/UITree.java 2008-12-14 18:07:10 UTC (rev 11758)
@@ -24,11 +24,14 @@
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
@@ -58,12 +61,15 @@
import org.richfaces.component.state.events.ExpandAllCommandEvent;
import org.richfaces.component.state.events.ExpandNodeCommandEvent;
import org.richfaces.component.state.events.TreeStateCommandEvent;
+import org.richfaces.event.AjaxExpandedEvent;
import org.richfaces.event.DragListener;
import org.richfaces.event.DropListener;
import org.richfaces.event.NodeExpandedEvent;
import org.richfaces.event.NodeExpandedListener;
import org.richfaces.event.NodeSelectedEvent;
import org.richfaces.event.NodeSelectedListener;
+import org.richfaces.event.TreeAjaxEvent;
+import org.richfaces.event.TreeAjaxEventType;
import org.richfaces.event.TreeListenerEventsProducer;
import org.richfaces.model.AbstractTreeDataModel;
import org.richfaces.model.CacheableTreeDataModel;
@@ -117,6 +123,10 @@
private UITreeNode defaultFacet;
+ private Set<Object> ajaxNodeKeys = null;
+
+ private Set<Object> nodeRequestKeys = null;
+
/**
* Name of EL variable for the tree node.
* This reference is needed to let this parent class
@@ -587,7 +597,7 @@
// fire node events
TreeEvents.invokeListenerBindings(this, event, getFacesContext());
-
+
if (event instanceof AjaxEvent) {
FacesContext facesContext = getFacesContext();
AjaxRendererUtils.addRegionsFromComponent(this, facesContext);
@@ -941,10 +951,11 @@
public Object saveState(FacesContext faces) {
- Object[] state = new Object[3];
+ Object[] state = new Object[4];
state[0] = super.saveState(faces);
state[1] = saveAttachedState(faces, defaultFacet);
state[2] = getTreeNodeVar();
+ state[3] = ajaxNodeKeys;
return state;
}
@@ -962,6 +973,7 @@
defaultFacet.setParent(this);
}
setTreeNodeVar((String) state[2]);
+ ajaxNodeKeys = (Set<Object>) state[3];
}
public String getResolvedDragIndicator(FacesContext facesContext) {
@@ -1191,6 +1203,120 @@
TreeState treeState = (TreeState) getComponentState();
treeState.transferQueuedNodes((TreeRowKey) getRowKey());
}
-}
+ /**
+ * @param o
+ * @since 3.3.0
+ */
+ public void addNodeRequestKey(Object o) {
+ if (o == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (nodeRequestKeys == null) {
+ nodeRequestKeys = new HashSet<Object>();
+ }
+
+ nodeRequestKeys.add(o);
+ }
+
+ /**
+ * @since 3.3.0
+ */
+ public void clearNodeRequestKeysSet() {
+ if (nodeRequestKeys != null) {
+ nodeRequestKeys.clear();
+ }
+ }
+
+ /**
+ * @param o
+ * @return
+ * @since 3.3.0
+ */
+ public boolean containsNodeRequestKey(Object o) {
+ return nodeRequestKeys != null && nodeRequestKeys.contains(o);
+ }
+
+ /**
+ * @param o
+ * @since 3.3.0
+ */
+ public void removeNodeRequestKey(Object o) {
+ if (nodeRequestKeys != null) {
+ nodeRequestKeys.remove(o);
+ }
+ }
+
+ /**
+ * @return
+ * @since 3.3.0
+ */
+ public Set<Object> getNodeRequestKeys() {
+ return nodeRequestKeys;
+ }
+
+ /**
+ * @return
+ * @since 3.3.0
+ */
+ public Set<Object> getAjaxNodeKeys() {
+ Set<Object> keys = null;
+ if (this.ajaxNodeKeys != null) {
+ keys = this.ajaxNodeKeys;
+ } else {
+ ValueExpression ve = this.getValueExpression("ajaxNodeKeys");
+ if (ve != null) {
+ keys = (Set<Object>) ve.getValue(getFacesContext().getELContext());
+ }
+ }
+
+ return keys;
+ }
+ /**
+ * @param keys
+ * @since 3.3.0
+ */
+ public void setAjaxNodeKeys(Set<Object> keys) {
+ this.ajaxNodeKeys = keys;
+ }
+
+ /**
+ * @return
+ * @since 3.3.0
+ */
+ public Set<Object> getAllAjaxNodeKeys() {
+ HashSet<Object> result = null;
+
+ Set<Object> ajaxNodeKeys = getAjaxNodeKeys();
+ if (ajaxNodeKeys != null) {
+ result = new HashSet<Object>(ajaxNodeKeys);
+ }
+
+ Set<Object> nodeRequestKeys = getNodeRequestKeys();
+ if (nodeRequestKeys != null) {
+ if (result != null) {
+ result.addAll(nodeRequestKeys);
+ } else {
+ result = new HashSet<Object>(nodeRequestKeys);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void addAjaxKeyEvent(FacesEvent event) {
+ if (event instanceof TreeAjaxEvent) {
+ TreeAjaxEvent treeAjaxEvent = (TreeAjaxEvent) event;
+ if (TreeAjaxEventType.EXPANSION.equals(treeAjaxEvent.getEventType())) {
+ addRequestKey(getRowKey());
+ } else {
+ super.addAjaxKeyEvent(event);
+ }
+ } else {
+ super.addAjaxKeyEvent(event);
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/ui/tree/src/main/java/org/richfaces/component/events/TreeEvents.java
===================================================================
--- trunk/ui/tree/src/main/java/org/richfaces/component/events/TreeEvents.java 2008-12-14 18:03:41 UTC (rev 11757)
+++ trunk/ui/tree/src/main/java/org/richfaces/component/events/TreeEvents.java 2008-12-14 18:07:10 UTC (rev 11758)
@@ -21,18 +21,20 @@
package org.richfaces.component.events;
+import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
-import org.ajax4jsf.event.AjaxEvent;
import org.richfaces.event.AjaxExpandedEvent;
import org.richfaces.event.AjaxSelectedEvent;
import org.richfaces.event.DragEvent;
import org.richfaces.event.DropEvent;
import org.richfaces.event.NodeExpandedEvent;
import org.richfaces.event.NodeSelectedEvent;
+import org.richfaces.event.TreeAjaxEvent;
+import org.richfaces.event.TreeAjaxEventType;
import org.richfaces.event.TreeListenerEventsProducer;
/**
@@ -52,15 +54,16 @@
throws AbortProcessingException {
MethodBinding binding = null;
+ UIComponent component = event.getComponent();
if (event instanceof NodeExpandedEvent) {
binding = eventsProducer.getChangeExpandListener();
if (event instanceof AjaxExpandedEvent) {
- new AjaxEvent(event.getComponent()).queue();
+ new TreeAjaxEvent(component, TreeAjaxEventType.EXPANSION).queue();
}
} else if (event instanceof AjaxSelectedEvent) {
if (eventsProducer.hasAjaxSubmitSelection()) {
binding = eventsProducer.getNodeSelectListener();
- new AjaxEvent(event.getComponent()).queue();
+ new TreeAjaxEvent(component, TreeAjaxEventType.SELECTION).queue();
}
} else if (event instanceof NodeSelectedEvent) {
binding = eventsProducer.getNodeSelectListener();
Modified: trunk/ui/tree/src/main/java/org/richfaces/renderkit/TreeRendererBase.java
===================================================================
--- trunk/ui/tree/src/main/java/org/richfaces/renderkit/TreeRendererBase.java 2008-12-14 18:03:41 UTC (rev 11757)
+++ trunk/ui/tree/src/main/java/org/richfaces/renderkit/TreeRendererBase.java 2008-12-14 18:07:10 UTC (rev 11758)
@@ -56,47 +56,32 @@
public abstract class TreeRendererBase extends CompositeRenderer {
- protected final static Comparator treeRowKeyComparator = new Comparator() {
+ protected static final class RowKeyHolder {
- public int compare(Object key1, Object key2) {
- TreeRowKey treeRowKey1 = (TreeRowKey) key1;
- TreeRowKey treeRowKey2 = (TreeRowKey) key2;
+ private TreeRowKey<Object> rowKey;
+
+ private boolean nodeKey;
+
+ public RowKeyHolder(TreeRowKey<Object> rowKey, boolean nodeKey) {
+ super();
+ this.rowKey = rowKey;
+ this.nodeKey = nodeKey;
+ }
+
+ public boolean isNodeKey() {
+ return nodeKey;
+ }
+
+ public TreeRowKey<Object> getRowKey() {
+ return rowKey;
+ }
- if (treeRowKey1 == null) {
- if (treeRowKey2 == null) {
- return 0;
- } else {
- return -1;
- }
- } else {
- if (treeRowKey2 == null) {
- return 1;
- }
- }
-
- Iterator iterator1 = treeRowKey1.iterator();
- Iterator iterator2 = treeRowKey2.iterator();
-
- while (iterator1.hasNext() && iterator2.hasNext()) {
- String id1 = iterator1.next().toString();
- String id2 = iterator2.next().toString();
-
- int cr = id1.compareTo(id2);
- if (cr != 0) {
- return cr;
- }
- }
-
- if (iterator1.hasNext()) {
- return 1;
- } else if (iterator2.hasNext()) {
- return -1;
- } else {
- return 0;
- }
+ @Override
+ public String toString() {
+ return this.getClass().getSimpleName() + "[" + rowKey + "]";
}
};
-
+
private final class RendererDataModelEventNavigator extends
TreeDataModelEventNavigator {
private final FacesContext context;
@@ -365,6 +350,38 @@
NSUtils.writeNameSpace(context, component);
}
+ private List<RowKeyHolder> getKeyHoldersList(Set subTreeKeys,
+ Set nodeKeys, String treePath) {
+
+ if (subTreeKeys != null && subTreeKeys.contains(null)) {
+ List<RowKeyHolder> list = new ArrayList<RowKeyHolder>(1);
+ list.add(new RowKeyHolder(null, false));
+ return list;
+ }
+
+ List<RowKeyHolder> list = new ArrayList<RowKeyHolder>((subTreeKeys == null ? 0 : subTreeKeys.size()) +
+ (nodeKeys == null ? 0 : nodeKeys.size()));
+
+ if (subTreeKeys != null) {
+ for (Object subTreeKey : subTreeKeys) {
+ list.add(new RowKeyHolder((TreeRowKey<Object>) subTreeKey, false));
+ }
+ }
+
+ if (nodeKeys != null) {
+ for (Object nodeKey : nodeKeys) {
+ TreeRowKey<Object> treeRowKey = (TreeRowKey<Object>) nodeKey;
+ if (treeRowKey != null && treeRowKey.depth() != 0) {
+ list.add(new RowKeyHolder(treeRowKey, true));
+ } else {
+ log.warn("Top node of the [" + treePath + "] tree cannot be re-rendered without subnodes");
+ }
+ }
+ }
+
+ return list;
+ }
+
public void encodeAjaxChildren(FacesContext context, UIComponent component,
String path, Set ids, Set renderedAreas) throws IOException {
super.encodeAjaxChildren(context, component, path, ids, renderedAreas);
@@ -389,68 +406,88 @@
writeNamespace(context, component);
List encodedAreaIds = new ArrayList();
-
+
try {
- Set ajaxKeys = tree.getAllAjaxKeys();
- if (ajaxKeys != null) {
- List sortedKeys = new ArrayList(ajaxKeys.size());
- sortedKeys.addAll(ajaxKeys);
- Collections.sort(sortedKeys, treeRowKeyComparator);
- Iterator ajaxKeysItr = sortedKeys.iterator();
- TreeRowKey lastKey = null;
- boolean nullRoot = false;
+ List<RowKeyHolder> keyHoldersList = getKeyHoldersList(
+ tree.getAllAjaxKeys(),
+ tree.getAllAjaxNodeKeys(),
+ id);
- while (!nullRoot && ajaxKeysItr.hasNext()) {
- TreeRowKey key = (TreeRowKey) ajaxKeysItr.next();
+ Collections.sort(keyHoldersList, new Comparator<RowKeyHolder>() {
- if (lastKey == null) {
- lastKey = key;
- } else {
- if (!lastKey.isSubKey(key)) {
- lastKey = key;
- } else {
- //skip nodes that's parent nodes have been rendered
- continue;
- }
- }
+ public int compare(RowKeyHolder o1, RowKeyHolder o2) {
+ int d1 = o1.rowKey == null ? 0 : o1.rowKey.depth();
+ int d2 = o2.rowKey == null ? 0 : o2.rowKey.depth();
- if (key == null || key.depth() == 0) {
- nullRoot = true;
- key = null;
+ return d1 < d2 ? -1 : (d2 > d1 ? 1 : 0);
+ }
+
+ });
+
+ List<RowKeyHolder> holders = new ArrayList<RowKeyHolder>();
+ for (RowKeyHolder holder : keyHoldersList) {
+ boolean isSubKey = false;
+
+ for (RowKeyHolder rowKeyHolder : holders) {
+ if (rowKeyHolder.rowKey == null ||
+ rowKeyHolder.rowKey.isSubKey(holder.rowKey)) {
+
+ isSubKey = true;
+ break;
}
+ }
- tree.setRowKey(context, key);
+ if (!isSubKey) {
+ holders.add(holder);
+ }
+ }
- if (key == null || tree.isRowAvailable()) {
- String treeClientId;
- if (key == null) {
- treeClientId = tree.getClientId(context);
- } else {
- treeClientId = tree.getNodeFacet().getClientId(context);
- }
+ Iterator<RowKeyHolder> ajaxKeysItr = holders.iterator();
+ while (ajaxKeysItr.hasNext()) {
+ RowKeyHolder keyHolder = ajaxKeysItr.next();
+ TreeRowKey key = keyHolder.getRowKey();
- String treeChildrenId = treeClientId + NamingContainer.SEPARATOR_CHAR + "childs";
-
- writeContent(context, tree, key);
- encodeScripts = true;
- renderedAreas.add(treeClientId);
- encodedAreaIds.add(treeClientId);
+ if (key != null && key.depth() == 0) {
+ key = null;
+ }
- renderedAreas.add(treeChildrenId);
- //encodedAreaIds.add(id+":childs");
+ tree.setRowKey(context, key);
+
+ if (key == null || tree.isRowAvailable()) {
+ String treeClientId;
+ if (key == null) {
+ treeClientId = tree.getClientId(context);
} else {
- String cid = tree.getClientId(context);
- String message = MessageFormat.format(
- "Failed to re-render tree node: {0} due to model data unavailability! " +
- "Maybe parent node should be re-rendered instead?",
- new Object[] { cid });
-
- ExternalContext externalContext = context.getExternalContext();
- externalContext.log(message);
+ treeClientId = tree.getNodeFacet().getClientId(context);
}
+
+ encodeScripts = true;
+
+ //should be added before children id
+ renderedAreas.add(treeClientId);
+
+ if (keyHolder.isNodeKey()) {
+ writeContent(context, tree, key, false);
+ } else {
+ writeContent(context, tree, key, true);
+ String treeChildrenId = treeClientId + NamingContainer.SEPARATOR_CHAR + "childs";
+ renderedAreas.add(treeChildrenId);
+ }
+
+ //add node to set of nodes refreshed by script
+ encodedAreaIds.add(treeClientId);
+ } else {
+ String cid = tree.getClientId(context);
+ String message = MessageFormat.format(
+ "Failed to re-render tree node: {0} due to model data unavailability! " +
+ "Maybe parent node should be re-rendered instead?",
+ new Object[] { cid });
+
+ ExternalContext externalContext = context.getExternalContext();
+ externalContext.log(message);
}
- //ajaxKeys.clear();
}
+ //ajaxKeys.clear();
} catch (Exception e) {
throw new FacesException(e);
} finally {
@@ -461,13 +498,9 @@
context.getExternalContext().log(e.getMessage(), e);
}
}
+
if (encodeScripts) {
writeScript(context, tree, encodedAreaIds, renderedAreas);
-
- String inputId = encodeSelectionStateInput(context, tree);
- if (inputId != null) {
- renderedAreas.add(inputId);
- }
}
responseWriter.endElement("div");
@@ -482,7 +515,7 @@
}
}
- public String encodeSelectionStateInput(FacesContext context, UITree tree) throws IOException {
+ protected String getSelectionValue(FacesContext context, UITree tree) {
String result = "";
TreeState treeState = (TreeState) tree.getComponentState();
TreeRowKey selectedNodeKey = treeState.getSelectedNode();
@@ -501,7 +534,11 @@
}
}
}
-
+
+ return result;
+ }
+
+ public String encodeSelectionStateInput(FacesContext context, UITree tree) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("input", tree);
writer.writeAttribute("type", "hidden", null);
@@ -509,7 +546,7 @@
writer.writeAttribute("id", selectionHolderInputId, null);
writer.writeAttribute("name", selectionHolderInputId, null);
- writer.writeAttribute("value", result, null);
+ writer.writeAttribute("value", ScriptUtils.toScript(getSelectionValue(context, tree)), null);
writer.endElement("input");
return selectionHolderInputId;
@@ -555,8 +592,10 @@
writer.writeText(varName + ".getNodeElements(" +
ScriptUtils.toScript(encodedAreaIds) + ");", null);
-
-
+
+ writer.writeText(varName + ".updateSelection(" +
+ ScriptUtils.toScript(getSelectionValue(context, tree)) + ");", null);
+
writer.endElement("script");
writer.endElement("div");
@@ -570,16 +609,16 @@
public void encodeChildren(FacesContext context, UIComponent component)
throws IOException {
- writeContent(context, (UITree) component, null);
+ writeContent(context, (UITree) component, null, true);
}
public void writeContent(final FacesContext context, final UITree input)
throws IOException {
- writeContent(context, input, null);
+ writeContent(context, input, null, true);
}
public void writeContent(final FacesContext context, final UITree input,
- TreeRowKey key) throws IOException {
+ TreeRowKey key, final boolean withSubnodes) throws IOException {
// simple flag can be used here because
// we cannot jump more than one level down until next node
// when rendering
@@ -600,7 +639,7 @@
TreeRange treeRange = new TreeRange() {
public boolean processChildren(TreeRowKey rowKey) {
- return stateRange.processChildren(rowKey);
+ return withSubnodes ? stateRange.processChildren(rowKey) : false;
}
public boolean processNode(TreeRowKey rowKey) {
@@ -683,4 +722,4 @@
public void setHasChildren(boolean hasChildren) {
this.hasChildren = hasChildren;
}
-}
\ No newline at end of file
+}
Modified: trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-item.js
===================================================================
--- trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-item.js 2008-12-14 18:03:41 UTC (rev 11757)
+++ trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-item.js 2008-12-14 18:07:10 UTC (rev 11758)
@@ -1,13 +1,19 @@
-Tree.Item = Class.create();
+Tree.Item = Class.create(Richfaces.TreeComposite);
-Tree.Item.findComponent = function(elt) {
- while (elt && (!elt.tagName || elt.tagName.toLowerCase() != 'table')) {
- elt = elt.parentNode;
+Tree.Item.findComponent = function(elt, axisFunction) {
+ var component;
+
+ while (elt && !((component = elt.object) instanceof Tree.Item)) {
+ if (axisFunction) {
+ elt = axisFunction(elt);
+ } else {
+ elt = elt.parentNode;
+ }
}
- return elt.object;
+ return component;
};
-
+
Tree.Item.fireCollapsionEvent = function(elt) {
return Tree.Item.findComponent(elt).fireCollapsionEvent();
};
@@ -16,13 +22,57 @@
return Tree.Item.findComponent(elt).fireExpansionEvent();
};
+Tree.Item.createItemForNode = function() {
+ var getComponentIndex = function(node) {
+ var idx = 0;
+ var n = node;
+
+ while (n) {
+ if (n.object instanceof Tree.Item) {
+ idx++;
+ }
+
+ n = n.previousSibling;
+
+ };
+
+ return idx;
+ };
+
+ var findParentComponent = function(node) {
+ var n = node.parentNode;
+ if (n) {
+ n = Richfaces.previous(n);
+ }
+
+ if (n) {
+ return n.object;
+ }
+ };
+
+ return function(node, tree) {
+ var replacedNode = $(node);
+
+ var pNode = findParentComponent(replacedNode) || tree;
+ var idx = getComponentIndex(replacedNode);
+
+ var item = new Tree.Item(replacedNode, tree, true);
+
+ pNode.addChild(item, idx);
-Tree.Item.prototype = {
- initialize: function(id, tree, parent, ajaxUpdate) {
- this.parent = parent;
+ return item;
+ };
+}();
+
+Tree.Item.addMethods({
+ initialize: function($super, id, tree, ajaxUpdate) {
+ $super();
+
this.tree = tree;
this.elements = {};
+ this["rich:destructor"] = "destroy";
+
var element;
if (typeof id == 'string') {
@@ -33,9 +83,11 @@
this.id = element.id;
}
+ element.component = this;
element.object = this;
var rows = element.rows;
+ this.elements.itemElement = element;
this.elements.mainRow = rows[0];
var sibling = element.nextSibling;
@@ -50,8 +102,24 @@
var iconId = this.id + Tree.ID_DEVIDER + Tree.ID_ICON;
var textId = this.id + Tree.ID_DEVIDER + Tree.ID_TEXT;
- this.getElements(element, ajaxUpdate);
+ var childsTd = Richfaces.next(element);
+ this.createSubNodes(childsTd);
+ if (ajaxUpdate && this.tree.showConnectingLines) {
+ var cell = element.rows[0].cells[0];
+ if (cell.style && cell.style.removeExpression) {
+ cell.style.backgroundImage = cell.currentStyle.backgroundImage;
+ cell.style.removeExpression('backgroundImage');
+ }
+
+ if (childsTd) {
+ if (childsTd.style && childsTd.style.removeExpression) {
+ childsTd.style.backgroundImage = childsTd.currentStyle.backgroundImage;
+ childsTd.style.removeExpression('backgroundImage');
+ }
+ }
+ }
+
var handles = null;
var cells = this.elements.mainRow.cells;
if ("NETSCAPE" == RichFaces.navigatorType()) {
@@ -105,7 +173,7 @@
if (dropOpts) {
this.enableDropzoneCursors(dropOpts.acceptCursor, dropOpts.rejectCursor);
}
-
+
this.observeEvents();
this.previousTextClassNames = null;
@@ -114,15 +182,18 @@
},
destroy: function() {
+ this.elements = undefined;
+
+ //TODO remove check
+ if (this.parent) {
+ this.parent.removeChild(this);
+ }
+
+ this.clearChildren();
+
if (this == this.tree.selectionManager.activeItem) {
this.tree.selectionManager.activeItem = null;
}
-
- for (var i = 0; i < this.childs.length; i++) {
- this.childs[i].destroy();
- }
-
- this.childs = null;
},
observeEvents: function() {
@@ -136,7 +207,7 @@
Event.observe(this.elements.iconElement, "mouseout", this.eventMouseOut);
Event.observe(this.elements.iconElement, "mouseover", this.eventMouseOver);
if (this.onContextMenu) {
- this.elements.iconElement.oncontextmenu = this.onContextMenu;
+ Event.observe(this.elements.iconElement, "contextmenu", this.onContextMenu);
}
}
@@ -146,11 +217,11 @@
Event.observe(this.elements.textElement, "mouseout", this.eventMouseOut);
Event.observe(this.elements.textElement, "mouseover", this.eventMouseOver);
if (this.onContextMenu) {
- this.elements.textElement.oncontextmenu = this.onContextMenu;
+ Event.observe(this.elements.textElement, "contextmenu", this.onContextMenu);
}
}
- if (this.tree.switchType=="client" && this.childs.length > 0) {
+ if (this.tree.switchType=="client" && this.hasChilds()) {
this.eventCollapsionClick = this.toggleCollapsion.bindAsEventListener(this);
var handleElt = this.tree.toggleOnClick ? this.elements.mainRow : this.elements.handle;
@@ -158,50 +229,24 @@
}
},
- getElements: function(element, ajaxUpdate) {
- this.childs = [];
-
- var childsTd = element.nextSibling;
-
- if (ajaxUpdate && this.tree.showConnectingLines) {
- var cell = element.rows[0].cells[0];
- if (cell.style && cell.style.removeExpression) {
- cell.style.backgroundImage = cell.currentStyle.backgroundImage;
- cell.style.removeExpression('backgroundImage');
- }
-
- if (childsTd) {
- if (childsTd.style && childsTd.style.removeExpression) {
- childsTd.style.backgroundImage = childsTd.currentStyle.backgroundImage;
- childsTd.style.removeExpression('backgroundImage');
- }
- }
- }
-
- if (childsTd) {
- var child = childsTd.firstChild;
+ createSubNodes: function(childrenTd) {
+ if (childrenTd) {
+ var child = childrenTd.firstChild;
while ( child != null )
{
if (child.nodeType == 1 && child.tagName.toLowerCase() == "table") {
- this.addChild(new Tree.Item(child, this.tree, this));
+ if (child.object instanceof Tree.Item) {
+ var item = child.object;
+ this.addChild(item);
+ } else {
+ this.addChild(new Tree.Item(child, this.tree));
+ }
}
child = child.nextSibling;
}
- /*
- for (var i = 0; i < childsTd.childNodes.length; i++) {
- var child = childsTd.childNodes[i];
- if (child.nodeType == 1 && child.tagName.toLowerCase() == "table") {
- this.addChild(new Tree.Item(child.id, this.tree, this));
- }
- }
- */
}
},
- addChild: function(child) {
- this.childs.push(child);
- },
-
fireExpansionEvent: function() {
var props = new Object();
props[Richfaces.TreeExpandEvent] = true;
@@ -455,32 +500,26 @@
}
},
- next: function() {
- var children = this.parent.childs;
+ _nextForAxis: function(axisFunction) {
+ var item;
- for (var i = 0; i < children.length - 1; i++) {
- if (children[i] == this) {
- return children[i + 1];
- }
+ if (this.elements && this.elements.itemElement) {
+ item = Tree.Item.findComponent(axisFunction(this.elements.itemElement), axisFunction);
}
- return this;
+ return item || this;
},
+
+ next: function() {
+ return this._nextForAxis(Richfaces.next);
+ },
previous: function() {
- var children = this.parent.childs;
-
- for (var i = 1; i < children.length; i++) {
- if (children[i] == this) {
- return children[i - 1];
- }
- }
-
- return this;
+ return this._nextForAxis(Richfaces.previous);
},
hasChilds: function() {
- return this.childs.length > 0;
+ return this.childs && this.childs.length > 0;
},
getElement: function() {
@@ -490,4 +529,5 @@
isLeaf: function() {
return !this.elements.handle;
}
-}
+
+});
Modified: trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-selection.js
===================================================================
--- trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-selection.js 2008-12-14 18:03:41 UTC (rev 11757)
+++ trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-selection.js 2008-12-14 18:07:10 UTC (rev 11758)
@@ -175,9 +175,7 @@
getPreviousItemForSelection: function(item) {
var prev = item.previous();
if (prev == item) {
- if (prev.parent == this.tree) {
- prev = item;
- } else {
+ if (item.parent != this.tree && item.parent) {
prev = item.parent;
}
} else if (!prev.isCollapsed() && prev.hasChilds()) {
Modified: trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree.js
===================================================================
--- trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree.js 2008-12-14 18:03:41 UTC (rev 11757)
+++ trunk/ui/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree.js 2008-12-14 18:07:10 UTC (rev 11758)
@@ -2,7 +2,51 @@
Richfaces.TreeExpandEvent = "Richfaces.TreeExpandEvent";
Richfaces.TreeCollapseEvent = "Richfaces.TreeCollapseEvent";
-Tree = Class.create();
+Richfaces.TreeComposite = Class.create({
+
+ parent: null,
+
+ initialize: function() {
+ this.childs = [];
+ },
+
+ removeChild: function(child) {
+ if (this.childs.length) {
+ var idx = this.childs.indexOf(child);
+ if (idx != -1) {
+ var removedChildren = this.childs.splice(idx, 1);
+ if (removedChildren) {
+ for (var i = 0; i < removedChildren.length; i++) {
+ removedChildren[i].parent = undefined;
+ }
+ }
+ }
+ }
+ },
+
+ addChild: function(child, idx) {
+ var start;
+ if (typeof idx != 'undefined') {
+ start = idx;
+ } else {
+ start = this.childs.length;
+ }
+
+ this.childs.splice(start, 0, child);
+ child.parent = this;
+ },
+
+ clearChildren: function() {
+ for (var i = 0; i < this.childs.length; i++) {
+ this.childs[i].parent = undefined;
+ }
+
+ this.childs = [];
+ }
+
+});
+
+Tree = Class.create(Richfaces.TreeComposite);
Tree.ID_DEVIDER = ":";
Tree.ID_CONTENT = "content";
Tree.ID_CHILDS_ROW = "childs";
@@ -19,8 +63,9 @@
Tree.CLASS_ITEM_COLLAPSED = "dr-tree-h-ic-line-clp";
Tree.CLASS_AJAX_SELECTED_LISTENER_FLAG = "ajax_selected_listener_flag";
-Tree.prototype = {
- initialize: function(id, input, switchType, events, onAjaxSelect, toggleOnClick, showConnectingLines) {
+Tree.addMethods({
+ initialize: function($super, id, input, switchType, events, onAjaxSelect, toggleOnClick, showConnectingLines) {
+ $super();
this.childs = [];
this.elements = {};
@@ -122,69 +167,41 @@
Tree.ID_DEVIDER + Tree.ID_CHILDS_ROW/* + Tree.ID_DEVIDER + Tree.ID_CHILDS_TD*/);
if (this.elements.contentTd) {
- for(var child = this.elements.contentTd.firstChild; child != null; child = child.nextSibling ) {
+ for(var child = this.elements.contentTd.firstChild; child != null; child = child.nextSibling ) {
if (child.nodeType == 1 && child.tagName.toLowerCase() == "table") {
- this.addChild(new Tree.Item(child, this, this, ajaxUpdate));
+ this.addChild(new Tree.Item(child, this, ajaxUpdate));
}
}
/*
for (var i = 0; i < this.elements.contentTd.childNodes.length; i++) {
var child = this.elements.contentTd.childNodes[i];
if (child.nodeType == 1 && child.tagName.toLowerCase() == "table") {
- this.addChild(new Tree.Item(child.id, this, this, this.childs.length, this.switchType, this.toggleOnClick));
+ this.addChild(new Tree.Item(child.id, this, this.childs.length, this.switchType, this.toggleOnClick));
}
}
*/
}
},
- addChild: function(child) {
- this.childs.push(child);
- },
-
getNodeElements: function(nodeIds) {
if (nodeIds) {
for (var i = 0; i < nodeIds.length; i++ ) {
var nodeId = nodeIds[i];
- if (nodeId != this.id) {
- this._getNodeElements(this, nodeId, nodeId.substring(0, nodeId.lastIndexOf('::')));
+ if (nodeId == this.id) {
+ this.clearChildren();
+ this.getElements(true);
} else {
- for (var i = 0; i < this.childs.length; i++) {
- var child = this.childs[i];
- child.destroy();
- }
-
- this.childs = [];
- this.getElements(true);
+ Tree.Item.createItemForNode(nodeId, this);
}
}
-
- //input holding selection has been refreshed
- this.input = $(this.inputId);
- this.selectionManager.restoreSelection();
}
},
-
- _getNodeElements: function(node, nodeId, sNodeId) {
- for (var i = 0; i < node.childs.length; i++) {
- var child = node.childs[i];
- var cid = child.id;
-
- if (cid == nodeId) {
- child.destroy();
- node.childs[i] = new Tree.Item(cid, this, child.parent, true);
- break;
- } else {
- var scid = cid.substring(0, cid.lastIndexOf('::'));
- if (sNodeId.substr(0, scid.length) == scid && sNodeId.charAt(scid.length) == ':') {
-
- this._getNodeElements(child, nodeId, sNodeId);
- break;
- }
- }
- }
+
+ updateSelection: function(selectedNode) {
+ this.input.value = selectedNode;
+ this.selectionManager.restoreSelection();
},
-
+
showNode: function(itemNode) {
var node = itemNode;
var offsetTopItem = 0;
@@ -206,6 +223,4 @@
getElement: function() {
return $(this.id);
}
-}
-
-
+});
\ No newline at end of file
Deleted: trunk/ui/tree/src/test/java/org/richfaces/renderkit/TreeRowKeyComparatorTest.java
===================================================================
--- trunk/ui/tree/src/test/java/org/richfaces/renderkit/TreeRowKeyComparatorTest.java 2008-12-14 18:03:41 UTC (rev 11757)
+++ trunk/ui/tree/src/test/java/org/richfaces/renderkit/TreeRowKeyComparatorTest.java 2008-12-14 18:07:10 UTC (rev 11758)
@@ -1,101 +0,0 @@
-/**
- * License Agreement.
- *
- * JBoss RichFaces - Ajax4jsf Component Library
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.renderkit;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-
-import org.richfaces.model.ListRowKey;
-
-import junit.framework.TestCase;
-
-/**
- *
- * <br /><br />
- *
- * Created 22.08.2007
- * @author Nick Belaevski
- * @since 3.1
- */
-
-public class TreeRowKeyComparatorTest extends TestCase {
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testComparator() throws Exception {
- Comparator comparator = TreeRendererBase.treeRowKeyComparator;
-
- ListRowKey emptyKey = new ListRowKey();
- ListRowKey key = new ListRowKey(new Integer(23));
- ListRowKey eqkey = new ListRowKey(new Integer(23));
- ListRowKey supKey = new ListRowKey(new ListRowKey(new Integer(23)), new Integer(34));
-
- ListRowKey predLongKey = new ListRowKey(new ListRowKey(new ListRowKey(new Integer(22)), new Integer(0)), new Integer(8));
- ListRowKey predKey = new ListRowKey(new Integer(22));
- ListRowKey predSupKey = new ListRowKey(new ListRowKey(new Integer(22)), new Integer(34));
- ListRowKey succKey = new ListRowKey(new ListRowKey(new Integer(25)), new Integer(34));
- ListRowKey succSupKey = new ListRowKey(new ListRowKey(new ListRowKey(new Integer(25)), new Integer(34)), new Integer(2));
-
- ArrayList list = new ArrayList();
- list.add(eqkey);
- list.add(succSupKey);
- list.add(succKey);
- list.add(predSupKey);
- list.add(predKey);
- list.add(supKey);
- list.add(key);
- list.add(null);
- list.add(emptyKey);
- list.add(null);
- list.add(predLongKey);
-
- Collections.sort(list, comparator);
-
- Iterator iterator = list.iterator();
- assertNull(iterator.next());
- assertNull(iterator.next());
- assertEquals(emptyKey, iterator.next());
- assertEquals(predKey, iterator.next());
- assertEquals(predLongKey, iterator.next());
- assertEquals(predSupKey, iterator.next());
- assertEquals(eqkey, iterator.next());
- assertEquals(key, iterator.next());
- assertEquals(supKey, iterator.next());
- assertEquals(succKey, iterator.next());
- assertEquals(succSupKey, iterator.next());
-
- }
-}
More information about the richfaces-svn-commits
mailing list