Changeset 243
- Timestamp:
- 2007-04-09 00:34:47 (3 years ago)
- Location:
- FCKeditor/branches/developers/mjk/editor/_source
- Files:
-
- 11 modified
-
classes/fckspecialcombo.js (modified) (2 diffs)
-
commandclasses/fck_othercommands.js (modified) (2 diffs)
-
internals/fckcommands.js (modified) (1 diff)
-
internals/fck_contextmenu.js (modified) (1 diff)
-
internals/fck_gecko.js (modified) (3 diffs)
-
internals/fck_ie.js (modified) (2 diffs)
-
internals/fckselection_gecko.js (modified) (1 diff)
-
internals/fckselection_ie.js (modified) (3 diffs)
-
internals/fckselection.js (modified) (1 diff)
-
internals/fcktablehandler.js (modified) (9 diffs)
-
internals/fcktools.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
FCKeditor/branches/developers/mjk/editor/_source/classes/fckspecialcombo.js
r132 r243 139 139 for ( var i in this.Items ) 140 140 { 141 if ( !this.Items[i] ) continue; 141 142 this.Items[i].className = this.Items[i].originalClass = 'SC_Item' ; 142 143 this.Items[i].Selected = false ; … … 176 177 177 178 this._OuterTable.className = isEnabled ? '' : 'SC_FieldDisabled' ; 179 } 180 181 FCKSpecialCombo.prototype.ClearItems = function () 182 { 183 if ( this.Items ) 184 { 185 for ( var key in this.Items ) 186 this.Items[key] = null ; 187 } 188 while (this._ItemsHolderEl.firstChild) 189 this._ItemsHolderEl.removeChild(this._ItemsHolderEl.firstChild); 178 190 } 179 191 -
FCKeditor/branches/developers/mjk/editor/_source/commandclasses/fck_othercommands.js
r174 r243 99 99 if ( typeof( fontSize ) == 'string' ) fontSize = parseInt(fontSize, 10) ; 100 100 101 if ( fontSize == null || fontSize == '' ) 102 { 103 // TODO: Remove font size attribute (Now it works with size 3. Will it work forever?) 104 FCK.ExecuteNamedCommand( 'FontSize', 3 ) ; 101 // If user wants the font size cleared, we have to find 102 // where the font size tag is and go clear it (if there's one) 103 if ( !fontSize || fontSize == null || fontSize == '' ) 104 { 105 var oFont = FCK.Selection.MoveToAncestorNode('FONT'); 106 if ( oFont && oFont.getAttribute("size") ) 107 { 108 //if the only thing here is SIZE, collapse the whole tag 109 if (oFont.attributes.length == 1 || 110 (oFont.outerHTML && oFont.outerHTML.search(/<FONT size=["]*\d["]*>/i))) 111 { 112 FCKTools.RemoveOuterTags(oFont); 113 } 114 else 115 oFont.removeAttribute("size"); 116 } 105 117 } 106 118 else 107 119 FCK.ExecuteNamedCommand( 'FontSize', fontSize ) ; 108 120 } 121 109 122 110 123 FCKFontSizeCommand.prototype.GetState = function() … … 380 393 } 381 394 } ; 395 396 var FCKAnchorDeleteCommand = function() 397 { 398 this.Name = 'AnchorDelete' ; 399 } 400 401 FCKAnchorDeleteCommand.prototype.Execute = function() 402 { 403 if (FCK.Selection.GetType() == 'Control') 404 { 405 FCK.Selection.Delete(); 406 } 407 else 408 { 409 var oFakeImage = FCK.Selection.GetSelectedElement() ; 410 if ( oFakeImage ) 411 { 412 if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckanchor') ) 413 oAnchor = FCK.GetRealElement( oFakeImage ) ; 414 else 415 oFakeImage = null ; 416 } 417 418 //Search for a real anchor 419 if ( !oFakeImage ) 420 { 421 oAnchor = FCK.Selection.MoveToAncestorNode( 'A' ) ; 422 if ( oAnchor ) 423 FCK.Selection.SelectNode( oAnchor ) ; 424 } 425 426 // If it's also a link, then just remove the name and exit 427 if ( oAnchor.href.length != 0 ) 428 { 429 oAnchor.removeAttribute( 'name' ) ; 430 // Remove temporary class for IE 431 if ( FCKBrowserInfo.IsIE ) 432 oAnchor.className = oAnchor.className.replace( FCKRegexLib.FCK_Class, '' ) ; 433 return ; 434 } 435 436 // We need to remove the anchor 437 // If we got a fake image, then just remove it and we're done 438 if ( oFakeImage ) 439 { 440 oFakeImage.parentNode.removeChild( oFakeImage ) ; 441 return ; 442 } 443 // Empty anchor, so just remove it 444 if ( oAnchor.innerHTML.length == 0 ) 445 { 446 oAnchor.parentNode.removeChild( oAnchor ) ; 447 return ; 448 } 449 // Anchor with content, leave the content 450 FCKTools.RemoveOuterTags( oAnchor ) ; 451 } 452 if ( FCKBrowserInfo.IsGecko ) 453 FCK.Selection.Collapse( true ) ; 454 } 455 456 FCKAnchorDeleteCommand.prototype.GetState = function() 457 { 458 return FCK.GetNamedCommandState( 'Unlink') ; 459 } 460 -
FCKeditor/branches/developers/mjk/editor/_source/internals/fckcommands.js
r174 r243 44 44 case 'Unlink' : oCommand = new FCKUnlinkCommand() ; break ; 45 45 case 'Anchor' : oCommand = new FCKDialogCommand( 'Anchor' , FCKLang.DlgAnchorTitle , 'dialog/fck_anchor.html' , 370, 170 ) ; break ; 46 case 'AnchorDelete' : oCommand = new FCKAnchorDeleteCommand() ; break ; 46 47 case 'BulletedList' : oCommand = new FCKDialogCommand( 'BulletedList', FCKLang.BulletedListProp , 'dialog/fck_listprop.html?UL' , 370, 170 ) ; break ; 47 48 case 'NumberedList' : oCommand = new FCKDialogCommand( 'NumberedList', FCKLang.NumberedListProp , 'dialog/fck_listprop.html?OL' , 370, 170 ) ; break ; -
FCKeditor/branches/developers/mjk/editor/_source/internals/fck_contextmenu.js
r202 r243 141 141 menu.AddSeparator() ; 142 142 menu.AddItem( 'Anchor', FCKLang.AnchorProp, 36 ) ; 143 menu.AddItem( 'AnchorDelete', FCKLang.AnchorDelete) ; 143 144 } 144 145 }} ; -
FCKeditor/branches/developers/mjk/editor/_source/internals/fck_gecko.js
r175 r243 39 39 } 40 40 41 //allow the table handler to handle mouse messages for dynamic table sizing 42 this._ExecMouseDown = function(e) 43 { 44 FCK.Events.FireEvent( "OnMouseDown",e ) ; 45 } 46 47 this._ExecMouseMove = function(e) 48 { 49 FCK.Events.FireEvent( "OnMouseMove",e ) ; 50 } 51 52 this._ExecMouseUp = function(e) 53 { 54 FCK.Events.FireEvent( "OnMouseUp",e ) ; 55 } 41 56 this.ExecOnSelectionChangeTimer = function() 42 57 { … … 63 78 FCK.ContextMenu._InnerContextMenu.SetMouseClickWindow( FCK.EditorWindow ) ; 64 79 FCK.ContextMenu._InnerContextMenu.AttachToElement( FCK.EditorDocument ) ; 80 81 //Hooks for table sizing 82 this.EditorDocument.addEventListener( 'mousedown', this._ExecMouseDown, true ) ; 83 this.EditorDocument.addEventListener( 'mouseup', this._ExecMouseUp, true ) ; 84 this.EditorDocument.addEventListener( 'mousemove', this._ExecMouseMove, true ) ; 85 65 86 } 66 87 … … 99 120 Copy : true 100 121 } ; 122 101 123 102 124 // ExecuteNamedCommand overload for Gecko. -
FCKeditor/branches/developers/mjk/editor/_source/internals/fck_ie.js
r202 r243 70 70 FCK.EditorWindow.event.returnValue = false ; 71 71 } 72 FCK.Events.FireEvent( "OnMouseUp",FCK.EditorWindow.event) ; 73 } 74 75 function Doc_OnMouseDown() 76 { 77 FCK.Events.FireEvent( "OnMouseDown",FCK.EditorWindow.event ) ; 78 } 79 80 function Doc_OnMouseMove() 81 { 82 FCK.Events.FireEvent( "OnMouseMove",FCK.EditorWindow.event) ; 72 83 } 73 84 … … 140 151 141 152 this.EditorDocument.attachEvent("ondblclick", Doc_OnDblClick ) ; 153 154 //additions for table sizing 155 this.EditorDocument.attachEvent( 'onmousedown', Doc_OnMouseDown ) ; 156 this.EditorDocument.attachEvent( 'onmousemove', Doc_OnMouseMove ) ; 157 142 158 143 159 // Catch cursor selection changes. -
FCKeditor/branches/developers/mjk/editor/_source/internals/fckselection_gecko.js
r132 r243 150 150 return oSel ; 151 151 } 152 153 // If FCKSelection is inside a table, return <td>'s so we can work on each 154 // one as a separate element 155 FCKSelection.TableNodes = function() 156 { 157 var oSel = FCK.EditorWindow.getSelection(); 158 var aNodes = new Array(); 159 if (this.HasAncestorNode("TABLE")) 160 { 161 var oTable = this.MoveToAncestorNode("TABLE"); 162 for (var r = 0; r < oTable.rows.length; r++) 163 { 164 for (var c = 0; c < oTable.rows[r].cells.length; c++) 165 { 166 if (oSel.containsNode(oTable.rows[r].cells[c],true)) 167 { 168 aNodes[aNodes.length] = oTable.rows[r].cells[c]; 169 } 170 } 171 } 172 } 173 return aNodes; 174 } 175 176 FCKSelection.SelectedHTML = function() 177 { 178 var oSel = FCK.EditorWindow.getSelection(); 179 var strHTML = ""; 180 //convert to a text range and walk the elements 181 for ( var i = 0 ; i < oSel.rangeCount ; i++ ) 182 { 183 var df = oSel.getRangeAt(i).cloneContents(); 184 185 for (var j = 0; j < df.childNodes.length; j++) 186 { 187 if (df.childNodes[j].nodeName == "#text") 188 {if (df.childNodes[j].textContent) strHTML += df.childNodes[j].textContent;} 189 else 190 strHTML += '<' + df.childNodes[j].nodeName + '>' 191 + df.childNodes[j].innerHTML 192 + '</' + df.childNodes[j].nodeName + '>'; 193 } 194 } 195 return strHTML; 196 } 197 -
FCKeditor/branches/developers/mjk/editor/_source/internals/fckselection_ie.js
r148 r243 46 46 { 47 47 case 'Control' : 48 if (!FCKSelection.GetSelectedElement()) return; 48 49 return FCKSelection.GetSelectedElement().parentElement ; 49 50 case 'None' : … … 110 111 } 111 112 113 // If FCKSelection is inside a table, return <td>'s so we can work on each 114 // one as a separate element 115 FCKSelection.TableNodes = function() 116 { 117 var oRange = FCK.EditorDocument.selection.createRange() ; 118 if (!oRange.htmlText.search(/<TD /)) return; 119 var oCellRange = oRange.duplicate(); 120 var oTable = this.MoveToAncestorNode("TABLE"); 121 if (!oTable) return; 122 var aNodes = new Array(); 123 for (var i = 0; i < oTable.cells.length; i++) 124 { 125 oCellRange.moveToElementText(oTable.cells[i]); 126 if (oRange.inRange(oCellRange)) 127 { 128 aNodes[aNodes.length] = oTable.cells[i]; 129 } 130 } 131 return aNodes; 132 } 133 112 134 // The "nodeTagName" parameter must be UPPER CASE. 113 135 FCKSelection.MoveToAncestorNode = function( nodeTagName ) … … 156 178 } 157 179 180 FCKSelection.SelectedHTML = function() 181 { 182 return FCK.EditorDocument.selection.createRange().htmlText; 183 } 158 184 185 -
FCKeditor/branches/developers/mjk/editor/_source/internals/fckselection.js
r132 r243 23 23 24 24 var FCKSelection = FCK.Selection = new Object() ; 25 26 //Return the nearest ancestor to the current position of the caret. 27 FCKSelection.GetCaretAncestor = function(strTag) 28 { 29 var e = FCKSelection.GetParentElement(); 30 var tn = e ? FCKTools.GetElementAscensor(e,strTag) : 31 FCKSelection.MoveToAncestorNode(strTag); 32 return tn; 33 } 34 35 FCKSelection.SelectedText = function() 36 { 37 return FCKTools.HTMLToText( this.SelectedHTML() ); 38 } -
FCKeditor/branches/developers/mjk/editor/_source/internals/fcktablehandler.js
r132 r243 1 1 /* 2 2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 3 * Copyright ( C) 2003-2007 Frederico Caldeira Knabben3 * Copyright ( C ) 2003-2007 Frederico Caldeira Knabben 4 4 * 5 5 * == BEGIN LICENSE == … … 8 8 * choice: 9 9 * 10 * - GNU General Public License Version 2 or later ( the "GPL")10 * - GNU General Public License Version 2 or later ( the "GPL" ) 11 11 * http://www.gnu.org/licenses/gpl.html 12 12 * 13 * - GNU Lesser General Public License Version 2.1 or later ( the "LGPL")13 * - GNU Lesser General Public License Version 2.1 or later ( the "LGPL" ) 14 14 * http://www.gnu.org/licenses/lgpl.html 15 15 * 16 * - Mozilla Public License Version 1.1 or later ( the "MPL")16 * - Mozilla Public License Version 1.1 or later ( the "MPL" ) 17 17 * http://www.mozilla.org/MPL/MPL-1.1.html 18 18 * … … 42 42 FCKTableHandler.DeleteRows = function( row ) 43 43 { 44 // If no row has been passed as a parameter, 45 // then get the row where the selection is placed in. 46 if ( !row ) 47 row = FCKSelection.MoveToAncestorNode( 'TR' ) ; 48 if ( !row ) return ; 44 // If no row has been passed as a parameer, 45 // then get the row( s ) containing the cells where the selection is placed in. 46 // If user selected multiple rows ( by selecting multiple cells ), walk 47 // the selected cell list and delete the rows containing the selected cells 48 if ( !row ) 49 { 50 var aCells = FCKTableHandler.GetSelectedCells(); 51 var aRowsToDelete = new Array(); 52 //queue up the rows -- it's possible ( and likely ) that we may get duplicates 53 for ( var i = 0; i < aCells.length; i++ ) 54 { 55 var oRow = FCKTools.GetElementAscensor( aCells[i],'TR' ); 56 aRowsToDelete[oRow.rowIndex] = oRow; 57 } 58 for ( var i = aRowsToDelete.length; i >= 0; i-- ) 59 { 60 if ( aRowsToDelete[i] ) 61 FCKTableHandler.DeleteRows( aRowsToDelete[i] ); 62 } 63 } 64 if ( !row ) return ; 49 65 50 66 // Get the row's table. … … 77 93 FCKSelection.SelectNode( table ) ; 78 94 FCKSelection.Collapse(); 79 table.parentNode.removeChild( table ) ; 95 96 // if the table is wrapped with a singleton <p> ( or something similar ), remove 97 // the surrounding tag -- which likely won't show after deletion anyway 98 if ( table.parentNode.children.length == 1 ) 99 table.parentNode.parentNode.removeChild( table.parentNode ); 100 else 101 table.parentNode.removeChild( table ) ; 80 102 } 81 103 … … 83 105 { 84 106 // Get the cell where the selection is placed in. 85 var oCell = FCKSelection.MoveToAncestorNode( 'TD') || FCKSelection.MoveToAncestorNode('TH') ;107 var oCell = FCKSelection.MoveToAncestorNode( 'TD' ) || FCKSelection.MoveToAncestorNode( 'TH' ) ; 86 108 87 109 if ( !oCell ) return ; … … 103 125 continue ; 104 126 105 oCell = oRow.cells[iIndex-1].cloneNode( false) ;127 oCell = oRow.cells[iIndex-1].cloneNode( false ) ; 106 128 107 129 if ( FCKBrowserInfo.IsGecko ) … … 119 141 } 120 142 121 FCKTableHandler.DeleteColumns = function() 122 { 123 // Get the cell where the selection is placed in. 124 var oCell = FCKSelection.MoveToAncestorNode('TD') || FCKSelection.MoveToAncestorNode('TH') ; 143 FCKTableHandler.DeleteColumns = function( oCell ) 144 { 145 // if user selected multiple cols ( by selecting multiple cells ), walk 146 // the selected cell list and delete the rows containing the selected cells 147 if ( !oCell ) 148 { 149 var aColsToDelete = FCKTableHandler.GetSelectedCells(); 150 for ( var i = aColsToDelete.length; i >= 0; i-- ) 151 { 152 if ( aColsToDelete[i] ) 153 FCKTableHandler.DeleteColumns( aColsToDelete[i] ); 154 } 155 return; 156 } 125 157 126 158 if ( !oCell ) return ; … … 300 332 return c ; 301 333 } 302 334 335 return null ; 336 } 337 338 // Get the cell location from a TableMap. Returns an array with an [x,y] location 339 FCKTableHandler._GetCellLocation = function( tableMap, cell ) 340 { 341 for ( var i = 0 ; i < tableMap.length; i++ ) 342 { 343 for ( var c = 0 ; c < tableMap[i].length ; c++ ) 344 { 345 if ( tableMap[i][c] == cell ) return [i,c]; 346 } 347 } 303 348 return null ; 304 349 } … … 384 429 } 385 430 } 431 432 //Returns TRUE if any cell has width set 433 FCKTableHandler.HasCellWidths = function( table ) 434 { 435 for ( var r = 0; r < table.rows.length; r++ ) 436 { 437 for ( var c = 0; c < table.rows[r].cells.length; c++ ) 438 { 439 if ( table.rows[r].cells[c].width ) return true; 440 } 441 } 442 return false; 443 } 444 445 //Clears all cell widths/heights ( letting the browser size everything ) 446 FCKTableHandler.ClearCellWidths = function( table ) 447 { 448 for ( var r = 0; r < table.rows.length; r++ ) 449 { 450 for ( var c = 0; c < table.rows[r].cells.length; c++ ) 451 { 452 table.rows[r].cells[c].width = ""; 453 table.rows[r].cells[c].height = ""; 454 table.rows[r].cells[c].removeAttribute( "WIDTH" ); 455 table.rows[r].cells[c].removeAttribute( "HEIGHT" ); 456 } 457 } 458 } 459 460 //Cleanup table widths. If bPercent, recalculates table widths in %. If bClear, 461 //moves all table widths as early as possible 462 463 FCKTableHandler.CleanupTableWidths = function( table, bPercent, bClear, aMapIn ) 464 { 465 var aMap = aMapIn ? aMapIn : this._CreateTableMap( table ) ; 466 var nCols = aMap[0].length; 467 var nRows = aMap.length; 468 var nTotalWidth = 0; 469 var aSizeCells = new Array(); 470 var aSizes = new Array(); 471 //work the table column-by-column 472 for ( var nCol = 0; nCol < nCols; nCol++ ) 473 { 474 var nMax = 0; 475 var oCell = null; 476 //walk the rows for a specific column -- find the topmost non-colspan'd item 477 //and the maximum pixel width ( according to the browser ) 478 for ( var nRow = 0; nRow < nRows; nRow++ ) 479 { 480 if ( aMap[nRow][nCol].colSpan > 1 ) continue; 481 //use topmost non-colspan'd cell to put the width in 482 if ( !oCell ) oCell = aMap[nRow][nCol]; 483 if ( aMap[nRow][nCol].offsetWidth > nMax ) nMax = aMap[nRow][nCol].offsetWidth; 484 } 485 aSizes[nCol] = nMax; 486 nTotalWidth += nMax; 487 aSizeCells[nCol] = oCell; 488 } 489 //if we were asked for percentage width, go through and convert the sizes to %. note 490 //that we do this based on the calculated width of all the cells; this is more 491 //reliable because offsetWidth, et al., includes table borders, padding, etc. 492 for ( var nCol = 0; nCol < aSizeCells.length; nCol++ ) 493 { 494 if ( bPercent ) 495 { 496 var nWidth = Math.round( 100 * (aSizeCells[nCol].offsetWidth/nTotalWidth )); 497 if ( nWidth == 0 ) nWidth = 1; 498 strWidth = nWidth + "%"; 499 } 500 else 501 { 502 strWidth = aSizes[nCol]; 503 } 504 505 //set all width attributes 506 for ( var nRow = 0; nRow < nRows; nRow++ ) 507 { 508 if ( aMap[nRow][nCol].colSpan == 1 ) 509 { 510 aMap[nRow][nCol].width = bClear ? '' : strWidth; 511 if ( bClear ) aMap[nRow][nCol].removeAttribute( "width" ); 512 aSizeCells[nCol].width = strWidth; 513 } 514 } 515 } 516 } 517 518 // Move the cursor into the next ( or previous ) cell 519 FCKTableHandler.MoveToNextCell = function( bRev ) 520 { 521 var aCells = FCKTableHandler.GetSelectedCells(); 522 if ( aCells.length == 0 ) return; 523 var oCell = aCells[0]; 524 var oNextCell = bRev ? oCell.previousSibling: oCell.nextSibling; 525 if ( !oNextCell ) 526 { 527 var oNext; 528 var oRow = FCKTools.GetElementAscensor( oCell,"TR" ); 529 if ( bRev ) 530 { 531 if ( !(oNext = oRow.previousSibling )) return; 532 oNextCell=oNext.cells[oNext.cells.length - 1]; 533 } 534 else 535 { 536 if ( !(oNext = oRow.nextSibling )) return; 537 oNextCell=oNext.cells[0]; 538 } 539 } 540 FCKSelection.SelectNode( oNextCell ); 541 FCKSelection.Collapse(); 542 } 543 ////////////////////////////////////////////////////////////////// 544 // Table Sizer 545 // 546 547 548 // Returns the closest sizeable cell to point (or the left of the specified point 549 // if between cells). Generally, this will be a heading cell (i.e. a cell in 550 // the first row). If *all* the candidate cells are colspan'd (heaven forbid), 551 // don't allow sizing. x and y are in client coordinates 552 553 FCKTableHandler.SizableCellFromPoint = function( table, ncx, ncy ) 554 { 555 var aRows = table.rows ; 556 var x = ncx - this._CalcPosition( table )[0]; 557 for ( var i = 0 ; i < aRows.length ; i++ ) 558 { 559 for ( var j = 0; j < aRows[i].cells.length - 1; j++ ) 560 { 561 if ( aRows[i].cells[j + 1].offsetLeft > x ) 562 { 563 if ( aRows[i].cells[j].colSpan < 2 ) 564 { 565 return aRows[i].cells[j]; 566 } 567 else 568 { 569 break; 570 } 571 } 572 } 573 } 574 return null; 575 } 576 577 // Creates the table resize bar. If a table resize bar is present, uses it. You 578 // must explicitly destroy the table resize bar with DestroyResizeBar after use. 579 FCKTableHandler.CreateResizeBar = function() 580 { 581 if ( this.ResizeBar ) return this.ResizeBar; 582 var oBar; 583 oBar = FCK.EditorDocument.createElement( "SPAN" ); 584 585 // setup the bar 586 oBar.id = '__FCKResizeBar'; 587 oBar.style.position = "absolute"; 588 oBar.style.top = "0px"; 589 oBar.style.left = "0px"; 590 oBar.style.height = "0px"; 591 oBar.style.width = "2px"; 592 oBar.style.borderLeft = "1px solid #0033FF"; 593 oBar.style.display = "none"; 594 oBar.style.cursor = "e-resize"; 595 596 FCK.EditorDocument.body.appendChild( oBar ); 597 this.ResizeBar = oBar; 598 return oBar; 599 } 600 601 // Destroys the table resize bar 602 FCKTableHandler.DestroyResizeBar = function() 603 { 604 if ( !this.ResizeBar ) return; 605 this.ResizeBar.parentNode.removeChild( FCKTableHandler.ResizeBar ); 606 this.ResizeBar = null; 607 } 608 609 // Figures out whether we want to size or let the browser do its thing. We can 610 // size if the table is the target and we're between cells, OR if we're on 611 // a table cell and on the far right edge of the cell within 3px of the edge 612 // ( allows us to easily size tables with thin borders ) 613 614 FCKTableHandler.CanSizeHere = function( ev, cell, tbl ) 615 { 616 var elem = ev.srcElement || ev.originalTarget; 617 var aCellLoc = this._CalcPosition( cell ); 618 var aTableLoc = this._CalcPosition( tbl ); 619 //in the td client area, but not on the edge 620 if ( elem != tbl ) return ( (aCellLoc[0] + cell.offsetWidth - ev.clientX ) < 3); 621 //on the table edge 622 if ( (aTableLoc[0] + tbl.offsetWidth - ev.clientX ) < 3 || 623 ( aTableLoc[0] - ev.clientX ) < 3 || 624 ( aTableLoc[1] + tbl.offsetHeight - ev.clientY < 3 ) || 625 ( aTableLoc[1] - ev.clientY < 3 )) return false; 626 return true; 627 } 628 629 630 // Sets up table sizing 631 FCKTableHandler.StartTableSizing = function( ev, cell, tbl ) 632 { 633 if ( !cell ) return null; 634 this.tableMap = this._CreateTableMap( tbl ) ; 635 var aCellLoc = this._GetCellLocation( this.tableMap, cell ); //returns [row,col] 636 if ( !aCellLoc ) return null; 637 //we're in the last column, so we can't size 638 if ( aCellLoc[1] == this.tableMap[aCellLoc[0]].length - 1 ) return null; 639 var nTarget = aCellLoc[1] + 1; 640 this.adjacentCell = null; 641 for ( var i=0; i < this.tableMap.length; i++ ) 642 { 643 if ( this.tableMap[i][nTarget].colSpan < 2 ) 644 { 645 this.adjacentCell = this.tableMap[i][nTarget]; 646 break; 647 } 648 } 649 if ( this.adjacentCell == null ) return null; //can't size, no adjacent col 650 this.targetCell = cell; 651 //ok. we have everything we need. off we go. 652 653 //create the resize bar 654 this.pixWidths = !( this.targetCell.width.search('%' ) == -1 || !this.targetCell.width); 655 var oVBar = this.CreateResizeBar(); 656 //oVBar.style.left = FCK.EditorDocument.body.scrollLeft + this._CalcPosition( cell ) + cell.offsetWidth; 657 //this.origPos = FCK.EditorDocument.body.scrollLeft + ev.clientX; 658 this.origPos = FCK.EditorDocument.body.scrollLeft + this._CalcPosition( cell )[0] + cell.offsetWidth; 659 oVBar.style.left = this.origPos; 660 oVBar.style.cursor = "e-resize"; 661 oVBar.setAttribute( "UNSELECTABLE","on" ); 662 tbl.setAttribute( "UNSELECTABLE","on" ); 663 this.sizeOffset = ev.clientX - this.origPos; 664 //minimum size is always the left edge of the cell + some safety margin. 665 //max size is always the right edge of the next cell - some safety margin 666 this.minSize = FCK.EditorDocument.body.scrollLeft + this._CalcPosition( cell )[0] + 10; 667 this.maxSize = FCK.EditorDocument.body.scrollLeft + this._CalcPosition( this.adjacentCell )[0] + this.adjacentCell.offsetWidth - 10; 668 oVBar.style.top = this._CalcPosition( tbl )[1]; 669 oVBar.style.height = tbl.clientHeight + ( tbl.border*2 ); 670 oVBar.style.display = "inline"; 671 this.CleanupTableWidths( tbl,false, true,this.tableMap ); 672 return true; 673 } 674 675 FCKTableHandler.FinishTableSizing = function() 676 { 677 var tbl = FCKTools.GetElementAscensor( this.targetCell,"TABLE" ); 678 var nTargetDiff = this.ResizeBar.offsetLeft - this.origPos; 679 //widths are in pixels after StartTableSizing, so this is safe 680 tbl.style.cursor = ''; 681 if ( tbl.runtimeStyle ) tbl.runtimeStyle.cursor = ''; 682 this.targetCell.width = parseInt( this.targetCell.width ) + nTargetDiff; 683 this.adjacentCell.width = parseInt( this.adjacentCell.width ) - nTargetDiff; 684 this.DestroyResizeBar(); 685 this.CleanupTableWidths( tbl,this.pixWidths,true,this.tableMap ); 686 this.targetCell = null; 687 this.origPos = null; 688 tbl.removeAttribute( "UNSELECTABLE" ); 689 if ( FCKBrowserInfo.IsGecko ) tbl.style.MozUserSelect = ""; 690 } 691 692 // Sizes the table to the given mouse position 693 FCKTableHandler.SizeTo = function( x ) 694 { 695 var nPos = x - this.sizeOffset; 696 if ( nPos > this.maxSize ) nPos = this.maxSize; 697 if ( nPos < this.minSize ) nPos = this.minSize; 698 //runtimeStyle is way faster under IE 699 if ( this.ResizeBar.runtimeStyle ) 700 this.ResizeBar.runtimeStyle.left = nPos; 701 else 702 this.ResizeBar.style.left = nPos; 703 if ( FCKBrowserInfo.IsGecko && FCK.EditorDocument.selection.type != 'None' ) FCK.EditorDocument.selection.collapse(); 704 } 705 706 // returns TRUE if we are actively sizing a table 707 FCKTableHandler.IsTableSizing = function() 708 { 709 return ( this.targetCell != null ); 710 } 711 712 // figure out where ( with respect to the edge of the parent ) a given table/cell is 713 FCKTableHandler._CalcPosition = function( ob ) 714 { 715 var oParent=ob; 716 var nY = 0; 717 var nX = 0; 718 while ( oParent && oParent.tagName != "BODY" ) 719 { 720 nX += oParent.offsetLeft; 721 nY += oParent.offsetTop; 722 oParent = oParent.offsetParent; 723 } 724 return [nX,nY]; 725 } 726 727 FCKTableHandler.tbl_MouseDown = function ( FCK, e ) 728 { 729 var elem = e.srcElement || e.originalTarget; 730 var strTag = elem ? elem.tagName.toUpperCase() : null; 731 //find the table we're part of, if we are 732 if ( elem && (strTag == 'TABLE' || strTag == 'TD' || strTag == 'TH' ) ) 733 { 734 FCKTableHandler.targetCell = null; 735 var oTable = FCKTools.GetElementAscensor( elem, "TABLE" ); 736 //figure out if there's a cell we can size 737 var oCell = FCKTableHandler.SizableCellFromPoint( oTable, e.clientX, e.clientY ); 738 if ( !oCell ) return true; 739 if ( FCKTableHandler.CanSizeHere( e,oCell,oTable ) ) 740 { 741 if ( FCKTableHandler.StartTableSizing( e,oCell, oTable ) ) 742 { 743 if ( oTable.runtimeStyle ) oTable.runtimeStyle.cursor = "e-resize"; 744 if ( FCKBrowserInfo.IsGecko ) oTable.style.MozUserSelect = "none"; 745 e.cancelBubble = true ; 746 e.returnValue = false ; 747 return false; 748 } 749 } 750 } 751 return true; 752 } 753 754 FCKTableHandler.tbl_MouseUp = function ( FCK, e ) 755 { 756 if ( FCKTableHandler.IsTableSizing( )) FCKTableHandler.FinishTableSizing(); 757 } 758 759 FCKTableHandler.tbl_MouseMove = function ( FCK, e ) 760 { 761 var elem = e.srcElement || e.originalTarget; 762 if ( FCKTableHandler.IsTableSizing() ) 763 { 764 FCKTableHandler.SizeTo( e.clientX ); 765 e.cancelBubble = true ; 766 e.returnValue = false ; 767 return false; 768 } 769 770 if ( elem.tagName.toUpperCase() == 'TABLE' ) 771 { 772 //let the browser handle global sizing and move if the user is on 773 //the RH edge of a table 774 if ( elem.clientWidth - e.offsetX < 3 || 775 elem.clientHeight - e.offsetY < 3 || 776 e.offsetX < 2 || e.offsetY < 2 ) 777 { 778 elem.style.cursor = ""; 779 return true; 780 } 781 //block browser sizing -- we're going to do it ourselves, thanks 782 if ( elem.runtimeStyle ) elem.runtimeStyle.cursor = "e-resize"; 783 e.cancelBubble = true ; 784 e.returnValue = false ; 785 return false; 786 } 787 else if ( elem.tagName.toUpperCase() == 'TD' ) 788 { 789 var tbl = FCKTools.GetElementAscensor( elem, "TABLE" ); 790 if ( e.offsetX >= (elem.offsetWidth - 4 )) 791 { 792 e.cancelBubble = true ; 793 e.returnValue = false ; 794 return false; 795 } 796 } 797 return true; 798 } 799 800 FCK.Events.AttachEvent( "OnMouseMove", FCKTableHandler.tbl_MouseMove ); 801 FCK.Events.AttachEvent( "OnMouseDown", FCKTableHandler.tbl_MouseDown ); 802 FCK.Events.AttachEvent( "OnMouseUp", FCKTableHandler.tbl_MouseUp ); -
FCKeditor/branches/developers/mjk/editor/_source/internals/fcktools.js
r146 r243 94 94 95 95 return text ; 96 } 97 98 //convert text to Proper Case 99 FCKTools.ProperCase = function( text ) 100 { 101 var strPC = text.toLowerCase(); 102 return strPC.replace(/(\S)(\S*\s*)/g, 103 function(str,p1,p2) 104 {return p1.toUpperCase()+p2}); 105 } 106 107 FCKTools.HTMLToText = function( st ) 108 { 109 if ( !st ) 110 return null; 111 112 st = st.replace(/<([^>]*?)>/g,''); 113 st = st.replace(/ /gi,' '); 114 return st; 96 115 } 97 116