Closed Bug 450410 Opened 16 years ago Closed 16 years ago

When manipulating the table DOM, an extra space is created when appending or insertingBefore a "tr" element with javascript.

Categories

(Core :: Layout: Tables, defect)

1.8 Branch
x86
Windows XP
defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 148810

People

(Reporter: travianTwister, Unassigned)

Details

(Keywords: css2, dom2)

User-Agent:       Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727; InfoPath.2)
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16

When manipulating the table DOM, an extra space is created when appending or insertingBefore a "tr" element with javascript.

This extra space is getting bigger the more the DOM table is manipulated and is a wrong space allocation for "tr" elements which already are removed in some cases...

Same counts when a "tr" element is set with absolute positioning (CSS).

Reproducible: Always

Steps to Reproduce:
1- Copy the HTML source code below 4 and paste it in a .html file
2- Open it
3- Drag the elements in the table


<html>
<head>
<script type='text/javascript'>
var dragObject  = null;
var tmpReplObj  = null;
var mouseOffset = null;
var Dclass = null;
var DropObj = null;

//////////////////////////////////////////////////////////
/////////////DISABLE SELECTION////////////////////////
function disableSelection(element){
    element.onselectstart = function() {
      return false;
    };
    element.unselectable = "on";
    element.style.MozUserSelect = "none";
    element.style.cursor = "default";
}
//////////////////////////////////////////////////////////
/////////////ENABLE SELECTION////////////////////////
function enableSelection(element){
    element.onselectstart ="";
    element.unselectable = "";
    element.style.MozUserSelect = "";
    element.style.cursor = "";
}

function getMouseOffset(target, ev){
	ev = ev || window.event;

	var docPos    = getPosition(target);
	var mousePos  = mouseCoords(ev);
	return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}

function getPosition(e){
	var left = 0;
	var top  = 0;

	while (e.offsetParent){
		left += e.offsetLeft;
		top  += e.offsetTop;
		e     = e.offsetParent;
	}

	left += e.offsetLeft;
	top  += e.offsetTop;

	return {x:left, y:top};
}
function mouseCoords(ev){
	if(ev.pageX || ev.pageY){
		return {x:ev.pageX, y:ev.pageY};
	}
	return {
		x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
		y:ev.clientY + document.body.scrollTop  - document.body.clientTop
	};
}

function mouseMove(ev){
   disableSelection(document.body);
   document.body.style.cursor='move';
	ev           = ev || window.event;
	var mousePos = mouseCoords(ev);

	if(dragObject){
	    if(!tmpReplObj)
		{
		 p=dragObject.parentNode;
		 tmpReplObj = dragObject.cloneNode(true);
		 dragObject.parentNode.insertBefore(tmpReplObj, dragObject);
		 //dragObject.parentNode.appendChild(tmpReplObj);
         tmpReplObj.id="tmpRpl"+dragObject.id;
		 
		 if(dragObject.tagName=="TR")
		 {
		  tmpReplObjL=tmpReplObj.cells.length;
		  for(i=0;i<tmpReplObjL;i++)
		  {
		   tmpReplObj.cells[i].innerHTML="&nbsp;";

		   //TOP BORDER
			tmpReplObj.cells[i].style.borderTopStyle='dashed';
			tmpReplObj.cells[i].style.borderTopColor='black';
		    tmpReplObj.cells[i].style.borderTopWidth='1px';
			
			//BOTTOM BORDER
			tmpReplObj.cells[i].style.borderBottomStyle='dashed';
			tmpReplObj.cells[i].style.borderBottomColor='black';
		    tmpReplObj.cells[i].style.borderBottomWidth='1px';
		   //LEFT BORDER first col
		   if(i==0)
		   {
		    tmpReplObj.cells[i].style.borderLeftStyle='dashed';
			tmpReplObj.cells[i].style.borderLeftColor='black';
		    tmpReplObj.cells[i].style.borderLeftWidth='1px';
		   }
		   //RIGHT BORDER last col
		   if(i==tmpReplObjL-1)
		   {
		    tmpReplObj.cells[i].style.borderRightStyle='dashed';
			tmpReplObj.cells[i].style.borderRightColor='black';
		    tmpReplObj.cells[i].style.borderRightWidth='1px';
		   }
		  }
		 }
		 else
		 {
		  tmpReplObj.innerHTML="&nbsp;";
		  tmpReplObj.style.borderStyle='dashed';
		  tmpReplObj.style.borderColor='black';
		  tmpReplObj.style.borderWidth='1px';
		 }
		}
		
		t=mousePos.y - mouseOffset.y;
		l=mousePos.x - mouseOffset.x;

		dragObject.style.position = "absolute";
		dragObject.style.backgroundColor='';
		dragObject.style.zIndex=100;
		dragObject.style.top      = t;
		dragObject.style.left     = l;
		

		for(dobj=0;dobj<DropObj.length;dobj++)
		{
		 if(DropObj[dobj]!=undefined)
		 {
		  //alert(mousePos.y+">="+DropObj[dobj].style.top);
		  if( (parseInt(mousePos.y,10)>=parseInt(DropObj[dobj].style.top,10)) && (parseInt(mousePos.y,10)<=(parseInt(DropObj[dobj].style.top,10)+parseInt(DropObj[dobj].style.height,10))) )
		  {
		   DropObj[dobj].style.backgroundColor='red';
		  }
		 }
		}

	document.getElementById('test').innerHTML= "cursorX="+ l +"cursorY="+t+"****";
	document.getElementById('test').innerHTML+= "offset Y="+ mouseOffset.y +" Offset X="+mouseOffset.x+"****";
	document.getElementById('test').innerHTML+= "cursorX="+mousePos.x+"cursorY="+mousePos.y;
	document.getElementById('test').innerHTML+= "length= "+dragObject.style.width +" height" +dragObject.style.height;
	
		return false;
	}
}

function mouseUp(){
	enableSelection(document.body);
	document.onmousemove = "";
	document.onmouseup   = "";
	document.body.style.cursor='auto';

	dragObject.style.top=tmpReplObj.style.top;
	dragObject.style.left=tmpReplObj.style.left;
	dragObject.style.position='';
    tmpReplObj.parentNode.replaceChild(dragObject,tmpReplObj);
	
	tmpReplObj  = null;
	dragObject = null;
	mouseOffset = null;
	Dclass = null;
	DropObj=null;
}

function drag(item,ev,fctmove,fctstop,dropClass,parentTable){
ev           = ev || item.event;

dragObject  = item;
w=parseInt(dragObject.offsetWidth,10)-parseInt(4,10);
h=parseInt(dragObject.offsetHeight,10)-parseInt(4,10);
dragObject.style.width=10000;
dragObject.style.height=h;
mouseOffset = getMouseOffset(item, ev);
Dclass = dropClass;

DropObj=new Array();
t=document.getElementById(parentTable).tBodies[0];

colors = new Array(14)
colors[0]="0"
colors[1]="1"
colors[2]="2"
colors[3]="3"
colors[4]="4"
colors[5]="5"
colors[5]="6"
colors[6]="7"
colors[7]="8"
colors[8]="9"
colors[9]="a"
colors[10]="b"
colors[11]="c"
colors[12]="d"
colors[13]="e"
colors[14]="f"

digit = new Array(5)
color=""
for (i=0;i<6;i++){
digit[i]=colors[Math.round(Math.random()*14)]
color = color+digit[i]
}

for(r=0;r<t.rows.length;r++)
{
 if( (t.rows[r].className==dropClass) && (t.rows[r]!=dragObject) )
 {

  t.rows[r].style.backgroundColor=color;
  t.rows[r].style.zIndex=0;
  t.rows[r].style.width=parseInt(t.rows[r].offsetWidth,10)-parseInt(4,10);
  t.rows[r].style.height=parseInt(t.rows[r].offsetHeight,10)-parseInt(4,10);
  
  DropPos=getPosition(t.rows[r]);
  if(t.rows[r].style.top=="")
  {
   t.rows[r].style.top=DropPos.y;
   t.rows[r].style.left=DropPos.x;
  }
  DropObj[r]=t.rows[r];
 // alert(DropObj[r]+"1st");
 }
 /*
 cells LOOP
 for(c=0;c<t.rows[r].cells.length;c++)
 {
  alert(t.rows[r].cells[c].className);
 }
 */
}


document.onmousemove = fctmove;
document.onmouseup   = fctstop;
}

</script>
</head>
<body>

<table border=1 id="mainDt">
	<colgroup>
		<col width="25%">
		<col width="75%">
	</colgroup>			   
<tr style='height:10px;' onmouseOver="this.style.borderStyle='dashed';this.style.borderColor='black';this.style.borderWidth='10px';">
	<th colspan='2'>Monday asdfsadf asdf fdsaadsf sfda  f dsafd sa fsd afd sa</th>
</tr>
<tr onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<th>Time</th>
	<th>Lesson**</th>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>1.00pm</td>
	<td>Pilates (Private Lesson)</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>2.00pm</td>
	<td  >Nursery Playdance</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>3.00pm</td>
	<td>Ballet Primary</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>4.00pm</td>
	<td>Football</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>5.00pm</td>
	<td>Boxing Primary</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>6.00pm</td>
	<td>Phone call</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>7.00pm</td>
	<td>Skype meeting</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>8.00pm</td>
	<td>Ballet Primary</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td>9.00pm</td>
	<td>Bar meeting</td>
</tr>
<tr class="droppable" onmousedown="drag(this,event,mouseMove,mouseUp,'droppable','mainDt');">
	<td >10.00pm</td>
	<td >Clubbing</td>
</tr>
</table>
<span id='test'></span>

</body>
</html>

Actual Results:  
An extra space is created every time the table DOM is modified with javascript. Even with the javascript replace function space is allocated for the "tr" element that disapeared.

Expected Results:  
There should be no extra space allocated for the "tr" element that no longer exists...

Create no extra space
My version of firefox is 

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16
Keywords: css2, dom2
Version: unspecified → 2.0 Branch
Component: General → Layout: Tables
Product: Firefox → Core
QA Contact: general → layout.tables
Version: 2.0 Branch → 1.8 Branch
Status: UNCONFIRMED → RESOLVED
Closed: 16 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.