[Commits] r2217 - in sandbox/camptocamp/geobretagne: examples lib/GeoExt/widgets/tree tests/lib/GeoExt/widgets/tree
commits at geoext.org
commits at geoext.org
Thu May 27 11:40:49 CEST 2010
Author: bbinet
Date: 2010-05-27 11:40:48 +0200 (Thu, 27 May 2010)
New Revision: 2217
Added:
sandbox/camptocamp/geobretagne/examples/tree-tools.html
sandbox/camptocamp/geobretagne/examples/tree-tools.js
Modified:
sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerNode.js
sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/tree/LayerNode.html
Log:
apply and merge patch-139-r1355-A0.diff from ticket #139.
Added: sandbox/camptocamp/geobretagne/examples/tree-tools.html
===================================================================
--- sandbox/camptocamp/geobretagne/examples/tree-tools.html (rev 0)
+++ sandbox/camptocamp/geobretagne/examples/tree-tools.html 2010-05-27 09:40:48 UTC (rev 2217)
@@ -0,0 +1,77 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>GeoExt Tree Tools</title>
+
+ <script type="text/javascript" src="http://extjs.cachefly.net/builds/ext-cdn-771.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+ <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/examples/shared/examples.css" />
+
+ <!--
+ <script type"text/javascript" src="../../ext/adapter/ext/ext-base.js"></script>
+ <script type"text/javascript" src="../../ext/ext-all-debug.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../ext/resources/css/ext-all.css"></script>
+ -->
+
+ <script src="http://openlayers.org/api/2.8/OpenLayers.js"></script>
+ <script type="text/javascript" src="../lib/GeoExt.js"></script>
+
+ <script type="text/javascript" src="tree-tools.js"></script>
+
+ <style type="text/css">
+ .gx-tree-layer-actions {
+ float: right;
+ }
+ .gx-tree-layer-action {
+ background-position: center center;
+ background-repeat: no-repeat;
+ border: 0 none;
+ height: 16px;
+ margin: 0;
+ padding: 0;
+ vertical-align: top;
+ width: 16px;
+ }
+ .gx-tree-layer-actions .delete {
+ background: transparent url(resources/img/delete.gif);
+ }
+ .gx-tree-layer-actions .up {
+ background: transparent url(resources/img/move_up.png);
+ }
+ .gx-tree-layer-actions .down {
+ background: transparent url(resources/img/move_down.png);
+ }
+ .gx-tree-layer-actions .tbar {
+ background: transparent url(resources/img/info.png);
+ }
+ .gx-tree-layer-actions .disabled {
+ opacity: 0.2;
+ }
+ .gx-toolbar {
+ background: none;
+ border-style: none;
+ left: 15;
+ }
+ .x-tree-node-el {
+ border-bottom: 1px solid #ddd;
+ }
+ .x-tree-node-collapsed .x-tree-node-icon, .x-tree-node-expanded .x-tree-node-icon, .x-tree-node-leaf .gx-tree-layer-icon {
+ width: 0px; !important;
+ }
+ </style>
+
+ </head>
+ <body>
+ <div id="desc">
+ <h1>GeoExt Tree Node UI</h1>
+
+ <p>This example shows how to add tools (actions) and components in
+ tree nodes. The tools added here allow moving the layers up and
+ down and deleting them. The component added for each node is a
+ toolbar including an opacity slider which acts on the node's
+ layer.</p>
+
+ <p>The js is not minified so it is readable. See
+ <a href="tree-tools.js">tree-tools.js</a>.</p>
+ </div>
+ </body>
+</html>
Added: sandbox/camptocamp/geobretagne/examples/tree-tools.js
===================================================================
--- sandbox/camptocamp/geobretagne/examples/tree-tools.js (rev 0)
+++ sandbox/camptocamp/geobretagne/examples/tree-tools.js 2010-05-27 09:40:48 UTC (rev 2217)
@@ -0,0 +1,233 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ *
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+Ext.namespace("GeoExt.examples");
+
+// this function creates a toolbar with a layer opacity
+// slider and an information button, it is used to
+// configure the layer node ui to add a toolbar
+// for each node in the layer tree
+GeoExt.examples.tbar = function(node, ct) {
+ return new Ext.Toolbar({
+ cls: "gx-toolbar",
+ buttons: [new GeoExt.LayerOpacitySlider({
+ layer: node.layer,
+ aggressive: true,
+ plugins: new GeoExt.LayerOpacitySliderTip(),
+ width: 100
+ })]
+ });
+};
+
+// this function takes action based on the "action"
+// parameter, it is used as a listener to layer
+// nodes' "action" events
+GeoExt.examples.act = function(node, action, evt) {
+ var layer = node.layer;
+ switch(action) {
+ case "down":
+ layer.map.raiseLayer(layer, -1);
+ break;
+ case "up":
+ layer.map.raiseLayer(layer, +1);
+ break;
+ case "delete":
+ layer.destroy();
+ break;
+ }
+};
+
+// a custom layer node UI class, for use with the second tree (see below).
+GeoExt.examples.CustomLayerNodeUI = Ext.extend(GeoExt.tree.LayerNodeUI, {
+ actions: [{
+ action: "delete",
+ qtip: "delete"
+ }, {
+ action: "up",
+ qtip: "move up",
+ update: function(el) {
+ // "this" references the tree node
+ var layer = this.layer, map = layer.map;
+ if (map.getLayerIndex(layer) == map.layers.length - 1) {
+ el.hide();
+ } else {
+ el.show();
+ }
+ }
+ }, {
+ action: "down",
+ qtip: "move down",
+ update: function(el) {
+ // "this" references the tree node
+ var layer = this.layer, map = layer.map;
+ if (map.getLayerIndex(layer) == 1) {
+ el.hide();
+ } else {
+ el.show();
+ }
+ }
+ }],
+ component: GeoExt.examples.tbar
+});
+
+Ext.onReady(function() {
+ Ext.QuickTips.init();
+
+ // the map panel
+ var mapPanel = new GeoExt.MapPanel({
+ border: true,
+ region: "center",
+ center: [146.1569825, -41.6109735],
+ zoom: 6,
+ layers: [
+ new OpenLayers.Layer.WMS("Tasmania State Boundaries",
+ "http://demo.opengeo.org/geoserver/wms", {
+ layers: "topp:tasmania_state_boundaries"
+ }, {
+ buffer: 0,
+ // exclude this layer from layer container nodes
+ displayInLayerSwitcher: false
+ }),
+ new OpenLayers.Layer.WMS("Water",
+ "http://demo.opengeo.org/geoserver/wms", {
+ layers: "topp:tasmania_water_bodies",
+ transparent: true,
+ format: "image/gif"
+ }, {
+ buffer: 0
+ }),
+ new OpenLayers.Layer.WMS("Cities",
+ "http://demo.opengeo.org/geoserver/wms", {
+ layers: "topp:tasmania_cities",
+ transparent: true,
+ format: "image/gif"
+ }, {
+ buffer: 0
+ }),
+ new OpenLayers.Layer.WMS("Tasmania Roads",
+ "http://demo.opengeo.org/geoserver/wms", {
+ layers: "topp:tasmania_roads",
+ transparent: true,
+ format: "image/gif"
+ }, {
+ buffer: 0
+ })
+ ]
+ });
+
+ // the first layer tree panel. If this tree the node actions and
+ // component are set using the loader's "baseAttrs" property.
+ var tree1 = new Ext.tree.TreePanel({
+ border: true,
+ region: "center",
+ title: "Layer Tree 1",
+ split: true,
+ collapsible: true,
+ autoScroll: true,
+ loader: {
+ applyLoader: false
+ },
+ root: {
+ nodeType: "gx_layercontainer",
+ loader: {
+ baseAttrs: {
+ actions: [{
+ action: "delete",
+ qtip: "delete"
+ }, {
+ action: "up",
+ qtip: "move up",
+ update: function(el) {
+ // "this" references the tree node
+ var layer = this.layer, map = layer.map;
+ if (map.getLayerIndex(layer) == map.layers.length - 1) {
+ el.addClass('disabled');
+ } else {
+ el.removeClass('disabled');
+ }
+ }
+ }, {
+ action: "down",
+ qtip: "move down",
+ update: function(el) {
+ // "this" references the tree node
+ var layer = this.layer, map = layer.map;
+ if (map.getLayerIndex(layer) == 1) {
+ el.addClass('disabled');
+ } else {
+ el.removeClass('disabled');
+ }
+ }
+ }],
+ checked: null,
+ component: GeoExt.examples.tbar
+ }
+ }
+ },
+ rootVisible: false,
+ lines: false,
+ listeners: {
+ action: GeoExt.examples.act
+ }
+ });
+
+ // the second layer tree panel. In this tree the CustomLayerNodeUI
+ // class is used for each node of the layer container.
+ var tree2 = new Ext.tree.TreePanel({
+ border: true,
+ region: "south",
+ height: 300,
+ title: "Layer Tree 2",
+ split: true,
+ collapsible: true,
+ autoScroll: true,
+ loader: {
+ applyLoader: false
+ },
+ root: {
+ nodeType: "gx_layercontainer",
+ loader: {
+ uiProviders: {
+ "ui": GeoExt.examples.CustomLayerNodeUI
+ },
+ baseAttrs: {
+ uiProvider: "ui"
+ }
+ }
+ },
+ rootVisible: false,
+ lines: false,
+ listeners: {
+ action: GeoExt.examples.act
+ }
+ });
+
+ // the viewport
+ new Ext.Viewport({
+ layout: "fit",
+ hideBorders: true,
+ items: {
+ layout: "border",
+ deferredRender: false,
+ items: [
+ mapPanel, {
+ region: "west",
+ width: 250,
+ layout: "border",
+ items: [
+ tree1,
+ tree2
+ ]
+ }, {
+ region: "east",
+ contentEl: "desc",
+ width: 250
+ }]
+ }
+ });
+});
Modified: sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerNode.js
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerNode.js 2010-05-27 09:31:56 UTC (rev 2216)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerNode.js 2010-05-27 09:40:48 UTC (rev 2217)
@@ -14,6 +14,14 @@
* Place in a separate file if this should be documented.
*/
GeoExt.tree.LayerNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+
+ /** private: constant[actionsCls]
+ */
+ actionsCls: "gx-tree-layer-actions",
+
+ /** private: constant[actionCls]
+ */
+ actionCls: "gx-tree-layer-action",
/** private: method[constructor]
*/
@@ -25,24 +33,69 @@
* :param bulkRender: ``Boolean``
*/
render: function(bulkRender) {
- var a = this.node.attributes;
- if (a.checked === undefined) {
- a.checked = this.node.layer.getVisibility();
+ var attr = this.node.attributes;
+ if (attr.checked === undefined) {
+ attr.checked = this.node.layer.getVisibility();
}
+ var rendered = this.rendered;
GeoExt.tree.LayerNodeUI.superclass.render.apply(this, arguments);
- var cb = this.checkbox;
- if(a.checkedGroup) {
- // replace the checkbox with a radio button
- var radio = Ext.DomHelper.insertAfter(cb,
- ['<input type="radio" name="', a.checkedGroup,
- '_checkbox" class="', cb.className,
- cb.checked ? '" checked="checked"' : '',
- '"></input>'].join(""));
- radio.defaultChecked = cb.defaultChecked;
- Ext.get(cb).remove();
- this.checkbox = radio;
+
+ if (!rendered) {
+ var cb = this.checkbox;
+ if(attr.checkedGroup) {
+ // replace the checkbox with a radio button
+ var radio = Ext.DomHelper.insertAfter(cb,
+ ['<input type="radio" name="', attr.checkedGroup,
+ '_checkbox" class="', cb.className,
+ cb.checked ? '" checked="checked"' : '',
+ '"></input>'].join(""));
+ radio.defaultChecked = cb.defaultChecked;
+ Ext.get(cb).remove();
+ this.checkbox = radio;
+ }
+
+ this.enforceOneVisible();
+
+ var actions = attr.actions || this.actions;
+ if(actions && actions.length > 0) {
+ var html = ['<div class="', this.actionsCls, '">'];
+ for(var i=0,len=actions.length; i<len; i++) {
+ var a = actions[i];
+ html = html.concat([
+ '<img id="'+this.node.id+'_'+a.action,
+ '" ext:qtip="'+a.qtip,
+ '" src="'+this.emptyIcon,
+ '" class="'+this.actionCls+' '+a.action+'" />'
+ ]);
+ }
+ html.concat(['</div>']);
+ Ext.DomHelper.insertFirst(this.elNode, html.join(""));
+ }
+ this.updateActions();
+
+ var component = attr.component || this.component;
+ if(component) {
+ var elt = Ext.DomHelper.append(this.elNode, [
+ {"tag": "div"}
+ ]);
+ if(typeof component == "function") {
+ component = component(this.node, elt);
+ } else if (typeof component == "object" &&
+ typeof component.fn == "function") {
+ component = component.fn.apply(
+ component.scope, [this.node, elt]
+ );
+ }
+ if(typeof component == "object" &&
+ typeof component.xtype == "string") {
+ component = Ext.ComponentMgr.create(component);
+ }
+ if(component instanceof Ext.Component) {
+ component.render(elt);
+ this.node.component = component;
+ }
+ }
}
- this.enforceOneVisible();
},
/** private: method[onClick]
@@ -51,10 +104,31 @@
onClick: function(e) {
if(e.getTarget('.x-tree-node-cb', 1)) {
this.toggleCheck(this.isChecked());
+ } else if(e.getTarget('.' + this.actionCls, 1)) {
+ var t = e.getTarget('.' + this.actionCls, 1);
+ var action = t.className.replace(this.actionCls + ' ', '');
+ if (this.fireEvent("action", this.node, action, e) === false) {
+ return;
+ }
} else {
GeoExt.tree.LayerNodeUI.superclass.onClick.apply(this, arguments);
}
},
+
+ /** private: method[updateActions]
+ *
+ * Update all the actions.
+ */
+ updateActions: function() {
+ var n = this.node;
+ var actions = n.attributes.actions || this.actions || [];
+ Ext.each(actions, function(a, index) {
+ var el = Ext.get(n.id + '_' + a.action);
+ if (el && typeof a.update == "function") {
+ a.update.call(n, el);
+ }
+ });
+ },
/** private: method[toggleCheck]
* :param value: ``Boolean``
@@ -79,7 +153,7 @@
var checkedCount = 0;
// enforce "not more than one visible"
Ext.each(checkedNodes, function(n){
- var l = n.layer
+ var l = n.layer;
if(!n.hidden && n.attributes.checkedGroup === group) {
checkedCount++;
if(l != layer && attributes.checked) {
@@ -175,6 +249,41 @@
* :class:`GeoExt.tree.LayerParamLoader` instance will be created, with
* the provided object as configuration.
*/
+
+ /** api: config[actions]
+ * ``Array(Object)`` An array of objects defining actions. An action is a
+ * clickable image in the node, it is defined with two properties:
+ * "action" and "qtip".
+ * * the "action" property provides the name of the action. It is used as
+ * the name of the ``img`` tag's class. The ``img`` tag being placed in a
+ * div whose class is "gx-tree-layer-actions" a CSS selector for the
+ * action is ``.gx-tree-layer-actions .action-name``. The name of the
+ * action is also set in "action" events for "action" listeners to know
+ * which action got clicked.
+ * * the "qtip" property references the tooltip displayed when the action
+ * image is hovered.
+ * This property applies only if the node is configured with a
+ * :class:`GeoExt.tree.LayerNodeUI` UI instance (which is the default).
+ */
+
+ /** api: config[component]
+ * ``Ext.Component or Object or Function`` This property is to be used
+ * when an Ext component is to be inserted in the node. This property can
+ * be used in several ways, it can reference
+ * * ``Ext.Component`` a component instance. In this case the provided
+ * component is just rendered in the node.
+ * * ``Object`` a component config (using ``xtype``). In this case the
+ * component is instantiated and then rendered in the node.
+ * * ``Function`` a function returning a component instance or config.
+ * This function is passed a reference to the layer node and to the Ext
+ * element (``Ext.Element``) into which the component is to be rendered,
+ * it must returned a component instance or config.
+ * * ``Object`` an object with a ``fn`` and ``scope`` properties. ``fn``
+ * references a function returning a component instance or config (like
+ * previously), ``scope`` is its execution scope.
+ * This property applies only if the node is configured with a
+ * :class:`GeoExt.tree.LayerNodeUI` UI instance (which is the default).
+ */
/** private: method[constructor]
* Private constructor override.
@@ -190,6 +299,17 @@
}
this.defaultUI = this.defaultUI || GeoExt.tree.LayerNodeUI;
+ this.addEvents(
+ /** api: event[action]
+ * Notifies listeners when an action is clicked, listeners are
+ * called with the following arguments:
+ * * :class:`GeoExt.tree.LayerNode` the layer node
+ * * ``String`` the action name
+ * * ``Ext.EventObject`` the event object
+ */
+ "action"
+ );
+
Ext.apply(this, {
layer: config.layer,
Modified: sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/tree/LayerNode.html
===================================================================
--- sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/tree/LayerNode.html 2010-05-27 09:31:56 UTC (rev 2216)
+++ sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/tree/LayerNode.html 2010-05-27 09:40:48 UTC (rev 2217)
@@ -180,7 +180,331 @@
node.destroy();
mapPanel.destroy();
}
-
+
+ function test_ui_node_action(t) {
+ t.plan(6);
+
+ // setup
+
+ var node = new GeoExt.tree.LayerNode({
+ layer: new OpenLayers.Layer(),
+ actions: [{
+ action: "foo-action",
+ qtip: "foo-qtip"
+ }]
+ });
+ var tree = new Ext.tree.TreePanel({
+ renderTo: "tree",
+ root: node
+ });
+ var ui = node.ui;
+ var elNode = Ext.fly(ui.elNode);
+
+ // test
+
+ t.ok(elNode.first().hasClass(ui.actionsCls),
+ "the actions div is at correct location and " +
+ "has a correct class");
+ t.ok(elNode.first().first() &&
+ elNode.first().first().hasClass(ui.actionCls) &&
+ elNode.first().first().hasClass("foo-action"),
+ "the action div is at correct location and " +
+ "has correct classes");
+
+ // simulate click
+ var log = [];
+ node.on({
+ action: function(n, a, e) {
+ log.push({n: n, a: a, e: e});
+ }
+ });
+ var e = {
+ getTarget: function(selector) {
+ if (selector == "." + ui.actionCls) {
+ return {
+ className: ui.actionCls + " foo-action"
+ };
+ }
+ }
+ };
+ var oc = GeoExt.tree.LayerNodeUI.superclass.onClick;
+ GeoExt.tree.LayerNodeUI.superclass.onClick = function() {};
+ ui.onClick(e);
+ t.eq(log.length, 1,
+ "click on action img triggers \"action\" event");
+ t.ok(log[0].n == node,
+ "\"action\" listener given expected node");
+ t.eq(log[0].a, "foo-action",
+ "\"action\" listener given expected action");
+ t.ok(log[0].e == e,
+ "\"action\" listener given expected event");
+ GeoExt.tree.LayerNodeUI.superclass.onClick = oc;
+
+ // teardown
+
+ tree.destroy();
+ }
+
+ function test_ui_node_ui_action(t) {
+ t.plan(6);
+
+ // setup
+
+ var UI = Ext.extend(GeoExt.tree.LayerNodeUI, {
+ actions: [{
+ action: "foo-action",
+ qtip: "foo-qtip"
+ }]
+ });
+
+ var node = new GeoExt.tree.LayerNode({
+ layer: new OpenLayers.Layer(),
+ uiProvider: UI
+ });
+ var tree = new Ext.tree.TreePanel({
+ renderTo: "tree",
+ root: node
+ });
+ var ui = node.ui;
+ var elNode = Ext.fly(ui.elNode);
+
+ // test
+
+ t.ok(elNode.first().hasClass(ui.actionsCls),
+ "the actions div is at correct location and " +
+ "has a correct class");
+ t.ok(elNode.first().first() &&
+ elNode.first().first().hasClass(ui.actionCls) &&
+ elNode.first().first().hasClass("foo-action"),
+ "the action div is at correct location and " +
+ "has correct classes");
+
+ // simulate click
+ var log = [];
+ node.on({
+ action: function(n, a, e) {
+ log.push({n: n, a: a, e: e});
+ }
+ });
+ var e = {
+ getTarget: function(selector) {
+ if (selector == "." + ui.actionCls) {
+ return {
+ className: ui.actionCls + " foo-action"
+ };
+ }
+ }
+ };
+ var oc = GeoExt.tree.LayerNodeUI.superclass.onClick;
+ GeoExt.tree.LayerNodeUI.superclass.onClick = function() {};
+ ui.onClick(e);
+ t.eq(log.length, 1,
+ "click on action img triggers \"action\" event");
+ t.ok(log[0].n == node,
+ "\"action\" listener given expected node");
+ t.eq(log[0].a, "foo-action",
+ "\"action\" listener given expected action");
+ t.ok(log[0].e == e,
+ "\"action\" listener given expected event");
+ GeoExt.tree.LayerNodeUI.superclass.onClick = oc;
+
+ // teardown
+
+ tree.destroy();
+ }
+
+ function test_ui_component_instance(t) {
+ t.plan(4);
+
+ // setup
+
+ var component = new Ext.Panel({
+ id: "foo-id",
+ cls: "foo-cls",
+ ctCls: "foo-ct-cls"
+ });
+ var node = new GeoExt.tree.LayerNode({
+ layer: new OpenLayers.Layer(),
+ component: component
+ });
+ var tree = new Ext.tree.TreePanel({
+ renderTo: "tree",
+ root: node
+ });
+ var ui = node.ui;
+ var elNode = Ext.fly(ui.elNode);
+
+ // test
+ t.ok(elNode.last().hasClass("foo-ct-cls"),
+ "the container div is at correct location and " +
+ "has a correct class");
+ t.ok(elNode.last().child("#foo-id"),
+ "the container div contains the panel div");
+ t.ok(elNode.last().child("#foo-id") &&
+ elNode.last().child("#foo-id").hasClass("foo-cls"),
+ "the panel div has a correct class");
+ t.ok(node.component === component,
+ "the component is set in the node");
+
+ // teardown
+
+ tree.destroy();
+ }
+
+ function test_ui_component_config(t) {
+ t.plan(3);
+
+ // setup
+
+ var component = {
+ xtype: "panel",
+ cls: "foo-cls",
+ ctCls: "foo-ct-cls"
+ };
+ var node = new GeoExt.tree.LayerNode({
+ layer: new OpenLayers.Layer(),
+ component: component
+ });
+ var tree = new Ext.tree.TreePanel({
+ renderTo: "tree",
+ root: node
+ });
+ var ui = node.ui;
+ var elNode = Ext.fly(ui.elNode);
+
+ // test
+ t.ok(elNode.last().hasClass("foo-ct-cls"),
+ "the container div is at correct location and " +
+ "has a correct class");
+ t.ok(elNode.last().child(".foo-cls") ,
+ "the container div contains the panel div, " +
+ "which has a correct class");
+ t.ok(node.component instanceof Ext.Panel,
+ "the component is set in the node");
+
+ // teardown
+
+ tree.destroy();
+ }
+
+ function test_ui_component_function(t) {
+ t.plan(16);
+
+ // setup
+
+ var component, node, tree, ui, elNode, log;
+
+ // test
+
+ // with a function returning a panel config
+ log = [];
+ component = function(n, e) {
+ log.push({n: n, e: e});
+ return {
+ xtype: "panel",
+ cls: "foo-cls",
+ ctCls: "foo-ct-cls"
+ };
+ };
+ node = new GeoExt.tree.LayerNode({
+ layer: new OpenLayers.Layer(),
+ component: component
+ });
+ tree = new Ext.tree.TreePanel({
+ renderTo: "tree",
+ root: node
+ });
+ ui = node.ui;
+ elNode = Ext.fly(ui.elNode);
+ t.eq(log.length, 1,
+ "[1] factory function called once");
+ t.ok(log.length > 0 && log[0].n === node,
+ "[1] factory function called with node");
+ t.ok(elNode.last().hasClass("foo-ct-cls"),
+ "[1] the container div is at correct location and " +
+ "has a correct class");
+ t.ok(elNode.last().child(".foo-cls") ,
+ "[1] the container div contains the panel div, " +
+ "which has a correct class");
+ t.ok(node.component instanceof Ext.Panel,
+ "[1] the component is set in the node");
+ tree.destroy();
+
+ // with a function returning a panel instance
+ log = [];
+ component = function(n, e) {
+ log.push({n: n, e: e});
+ return new Ext.Panel({
+ cls: "foo-cls",
+ ctCls: "foo-ct-cls"
+ });
+ };
+ node = new GeoExt.tree.LayerNode({
+ layer: new OpenLayers.Layer(),
+ component: component
+ });
+ tree = new Ext.tree.TreePanel({
+ renderTo: "tree",
+ root: node
+ });
+ ui = node.ui;
+ elNode = Ext.fly(ui.elNode);
+ t.eq(log.length, 1,
+ "[2] factory function called once");
+ t.ok(log.length > 0 && log[0].n === node,
+ "[2] factory function called with node");
+ t.ok(elNode.last().hasClass("foo-ct-cls"),
+ "[2] the container div is at correct location and " +
+ "has a correct class");
+ t.ok(elNode.last().child(".foo-cls") ,
+ "[2] the container div contains the panel div, " +
+ "which has a correct class");
+ t.ok(node.component instanceof Ext.Panel,
+ "[2] the component is set in the node");
+ tree.destroy();
+
+ // with an object with fn and scope properties
+ log = [];
+ var scope = {"some": "scope"};
+ component = {
+ fn: function(n, e) {
+ log.push({n: n, e: e, s: this});
+ return new Ext.Panel({
+ cls: "foo-cls",
+ ctCls: "foo-ct-cls"
+ });
+ },
+ scope: scope
+ };
+ node = new GeoExt.tree.LayerNode({
+ layer: new OpenLayers.Layer(),
+ component: component
+ });
+ tree = new Ext.tree.TreePanel({
+ renderTo: "tree",
+ root: node
+ });
+ ui = node.ui;
+ elNode = Ext.fly(ui.elNode);
+ t.eq(log.length, 1,
+ "[3] factory function called once");
+ t.ok(log.length > 0 && log[0].n === node,
+ "[3] factory function called with node");
+ t.ok(log.length > 0 && log[0].s === scope,
+ "[3] factory function called with correct scope");
+ t.ok(elNode.last().hasClass("foo-ct-cls"),
+ "[3] the container div is at correct location and " +
+ "has a correct class");
+ t.ok(elNode.last().child(".foo-cls") ,
+ "[3] the container div contains the panel div, " +
+ "which has a correct class");
+ t.ok(node.component instanceof Ext.Panel,
+ "[3] the component is set in the node");
+ tree.destroy();
+
+ // teardown
+ }
+
</script>
</head>
<body>
More information about the Commits
mailing list