PDA

View Full Version : [FIXED-1402] Global Variables in ExtJs 3.3.0 (len and r)



uptodate
10 Nov 2010, 11:59 PM
In ExtJs there are global variables when drag and drop.

See Example :
http://dev.sencha.com/deploy/ext/examples/dd/dnd_grid_to_grid.html

The variables are :


len
r


Here the DOM from Firebug

23264


Can you give me a bugfix for this problem ?

Animal
11 Nov 2010, 12:46 AM
Ext is the namespace, that has to be there.

id is the browser window element id.

len that should not be there. Are tou sure it leaked out of Ext code?

r also should not be there, again, are you sure it's not your code?

swfobject, I think it's supposed to be there.

undefined is explicitly put there as a bugfix for old browsers:



// for old browsers
window.undefined = window.undefined;

uptodate
11 Nov 2010, 1:41 AM
I am sure that the variable coming from you.
I`m using your live example online, not local.


The variable len is set after the page is load.

The r variable is set when I Drag and Drop the records.


Have you forget in firebug to reload the DOM ?


Here a picture :

23274

uptodate
11 Nov 2010, 1:48 AM
How to reproduce the r variable in http://dev.sencha.com/deploy/ext/examples/dd/dnd_grid_to_grid.html :

1. Select the first record and drop in the Second Grid.

2. Select in the First Grid the first Row and select in the Second Grid the first Row

3. Drag the first selected Record (from the First Grid) and Drop in the Second Grid.

Now you have the r Variable in the DOM

Animal
11 Nov 2010, 5:42 AM
Well, there's no way it's coming from me, you are not running my app.

They may well be coming from ExtJS.

Animal
11 Nov 2010, 5:46 AM
I cannot reproduce that running their example here.

uptodate
11 Nov 2010, 5:47 AM
Sorry for my bad English. Of course I mean that the variable comes from the ExtJs-Libary

mankz
11 Nov 2010, 5:56 AM
the 'len' leak is in Store add method:



add : function(records) {
var i, record, index;

records = [].concat(records);
if (records.length < 1) {
return;
}

for (i = 0, len = records.length; i < len; i++) {
record = records[i];

record.join(this);

if (record.dirty || record.phantom) {
this.modified.push(record);
}
}

index = this.data.length;
this.data.addAll(records);

if (this.snapshot) {
this.snapshot.addAll(records);
}

this.fireEvent('add', this, records, index);
},


The 'r' leak I cannot reproduce.

mankz
11 Nov 2010, 5:58 AM
And loadRecords:



loadRecords : function(o, options, success){
var i;

if (this.isDestroyed === true) {
return;
}
if(!o || success === false){
if(success !== false){
this.fireEvent('load', this, [], options);
}
if(options.callback){
options.callback.call(options.scope || this, [], options, false, o);
}
return;
}
var r = o.records, t = o.totalRecords || r.length;
if(!options || options.add !== true){
if(this.pruneModifiedRecords){
this.modified = [];
}
for(i = 0, len = r.length; i < len; i++){
r[i].join(this);
}
if(this.snapshot){
this.data = this.snapshot;
delete this.snapshot;
}
this.clearData();
this.data.addAll(r);
this.totalLength = t;
this.applySort();
this.fireEvent('datachanged', this);
}else{
var toAdd = [],
rec,
cnt = 0;
for(i = 0, len = r.length; i < len; ++i){
rec = r[i];
if(this.indexOfId(rec.id) > -1){
this.doUpdate(rec);
}else{
toAdd.push(rec);
++cnt;
}
}
this.totalLength = Math.max(t, this.data.length + cnt);
this.add(toAdd);
}
this.fireEvent('load', this, r, options);
if(options.callback){
options.callback.call(options.scope || this, r, options, true);
}
},

uptodate
11 Nov 2010, 6:01 AM
r - variable

The problem only occurs when in the Second Grid a Row is selected. And then you drag from the First Grid to the Second Grid.

When in the Second Grid not selected the variable is not created

mankz
11 Nov 2010, 6:05 AM
'r' is leaked here (Ext.grid.RowSelectionModel):



onRefresh : function(){
var ds = this.grid.store,
s = this.getSelections(),
i = 0,
len = s.length,
index;

this.silent = true;
this.clearSelections(true);
for(; i < len; i++){
r = s[i];
if((index = ds.indexOfId(r.id)) != -1){
this.selectRow(index, true);
}
}
if(s.length != this.selections.getCount()){
this.fireEvent('selectionchange', this);
}
this.silent = false;
},

mankz
11 Nov 2010, 6:07 AM
'len' also leaked in Store insert method.


insert : function(index, records) {
var i, record;

records = [].concat(records);
for (i = 0, len = records.length; i < len; i++) {
record = records[i];

this.data.insert(index + i, record);
record.join(this);

if (record.dirty || record.phantom) {
this.modified.push(record);
}
}

if (this.snapshot) {
this.snapshot.addAll(records);
}

this.fireEvent('add', this, records, index);
},

meroy
11 Nov 2010, 12:04 PM
Thanks @mankz. It looks like you have found them all.

Thanks for the report @uptodate.

These have been fixed in SVN for 3.3.x.

uptodate
11 Nov 2010, 10:43 PM
i found a global variable : flexedHeight
in

Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {

align : 'left',
type: 'vbox',



calculateChildBoxes: function(visibleItems, targetSize) {
var visibleCount = visibleItems.length,
padding = this.padding,
topOffset = padding.top,
leftOffset = padding.left,
paddingVert = topOffset + padding.bottom,
paddingHoriz = leftOffset + padding.right,
width = targetSize.width - this.scrollOffset,
height = targetSize.height,
availWidth = Math.max(0, width - paddingHoriz),
isStart = this.pack == 'start',
isCenter = this.pack == 'center',
isEnd = this.pack == 'end',
nonFlexHeight= 0,
maxWidth = 0,
totalFlex = 0,
desiredHeight= 0,
minimumHeight= 0,

boxes = [],


child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
horizMargins, vertMargins, stretchWidth;

for (i = 0; i < visibleCount; i++) {
child = visibleItems[i];
childHeight = child.height;
childWidth = child.width;
canLayout = !child.hasLayout && typeof child.doLayout == 'function';

if (typeof childHeight != 'number') {

if (child.flex && !childHeight) {
totalFlex += child.flex;

} else {


if (!childHeight && canLayout) {
child.doLayout();
}
childSize = child.getSize();
childWidth = childSize.width;
childHeight = childSize.height;
}
}

childMargins = child.margins;
vertMargins = childMargins.top + childMargins.bottom;
nonFlexHeight += vertMargins + (childHeight || 0);
desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight);
minimumHeight += vertMargins + (child.minHeight || childHeight || 0);

if (typeof childWidth != 'number') {
if (canLayout) {
child.doLayout();
}
childWidth = child.getWidth();
}
maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);

boxes.push({
component: child,
height : childHeight || undefined,
width : childWidth || undefined
});
}

var shortfall = desiredHeight - height,
tooNarrow = minimumHeight > height;

var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));

if (tooNarrow) {
for (i = 0, length = visibleCount; i < length; i++) {
boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height;
}
} else {


if (shortfall > 0) {
var minHeights = [];

for (var index = 0, length = visibleCount; index < length; index++) {
var item = visibleItems[index],
minHeight = item.minHeight || 0;


if (item.flex) {
boxes[index].height = minHeight;
} else {
minHeights.push({
minHeight: minHeight,
available: boxes[index].height - minHeight,
index : index
});
}
}

minHeights.sort(function(a, b) {
return a.available > b.available ? 1 : -1;
});

for (var i = 0, length = minHeights.length; i < length; i++) {
var itemIndex = minHeights[i].index;
if (itemIndex == undefined) {
continue;
}
var item = visibleItems[itemIndex],
box = boxes[itemIndex],
oldHeight = box.height,
minHeight = item.minHeight,
newHeight = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))),
reduction = oldHeight - newHeight;
boxes[itemIndex].height = newHeight;
shortfall -= reduction;
}
} else {

var remainingHeight = availableHeight,
remainingFlex = totalFlex;


for (i = 0; i < visibleCount; i++) {
child = visibleItems[i];
calcs = boxes[i];
childMargins = child.margins;
horizMargins = childMargins.left + childMargins.right;
if (isStart && child.flex && !child.height) {
flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight);
remainingHeight -= flexedHeight;
remainingFlex -= child.flex;
calcs.height = flexedHeight;
calcs.dirtySize = true;
}
}
}
}
if (isCenter) {
topOffset += availableHeight / 2;
} else if (isEnd) {
topOffset += availableHeight;
}

for (i = 0; i < visibleCount; i++) {
child = visibleItems[i];
calcs = boxes[i];
childMargins = child.margins;
topOffset += childMargins.top;
horizMargins = childMargins.left + childMargins.right;

calcs.left = leftOffset + childMargins.left;
calcs.top = topOffset;

switch (this.align) {
case 'stretch':
stretchWidth = availWidth - horizMargins;
calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
calcs.dirtySize = true;
break;
case 'stretchmax':
stretchWidth = maxWidth - horizMargins;
calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
calcs.dirtySize = true;
break;
case 'center':
var diff = availWidth - calcs.width - horizMargins;
if (diff > 0) {
calcs.left = leftOffset + horizMargins + (diff / 2);
}
}
topOffset += calcs.height + childMargins.bottom;
}

return {
boxes: boxes,
meta : {
maxWidth : maxWidth,
nonFlexHeight: nonFlexHeight,
desiredHeight: desiredHeight,
minimumHeight: minimumHeight,
shortfall : desiredHeight - height,
tooNarrow : tooNarrow
}
};
}
});

meroy
11 Jan 2011, 11:37 AM
@uptodate: Thanks for the post. That is now fixed in SVN (3.3.x branch).