Changeset 308

Show
Ignore:
Timestamp:
2007-05-18 17:59:45 (17 months ago)
Author:
fredck
Message:

Fixed #71 and #243 : The editor now takes care to not create invalid nested block elements, like creating <form> or <hr> inside <p>.

Location:
FCKeditor/trunk/editor
Files:
26 modified

Legend:

Unmodified
Added
Removed
  • FCKeditor/trunk/editor/dialog/fck_anchor.html

    r132 r308  
    115115        { 
    116116                // Nothing was selected, so now just create a normal A 
    117                 oAnchor = oEditor.FCK.CreateElement( 'a' ) ; 
     117                oAnchor = oEditor.FCK.InsertElement( 'a' ) ; 
    118118        } 
    119119        else 
  • FCKeditor/trunk/editor/dialog/fck_button.html

    r132 r308  
    6262                oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ; 
    6363                oActiveEl.type = GetE('txtType').value ; 
    64                 oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ; 
     64                oActiveEl = oEditor.FCK.InsertElement( oActiveEl ) ; 
    6565        } 
    6666 
  • FCKeditor/trunk/editor/dialog/fck_checkbox.html

    r132 r308  
    6060                oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ; 
    6161                oActiveEl.type = 'checkbox' ; 
    62                 oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ; 
     62                oActiveEl = oEditor.FCK.InsertElement( oActiveEl ) ; 
    6363        } 
    6464 
  • FCKeditor/trunk/editor/dialog/fck_flash/fck_flash.js

    r251 r308  
    134134                oFakeImage      = oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__Flash', oEmbed ) ; 
    135135                oFakeImage.setAttribute( '_fckflash', 'true', 0 ) ; 
    136                 oFakeImage      = FCK.InsertElementAndGetIt( oFakeImage ) ; 
     136                oFakeImage      = FCK.InsertElement( oFakeImage ) ; 
    137137        } 
    138138        else 
  • FCKeditor/trunk/editor/dialog/fck_form.html

    r132 r308  
    1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
     1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
    22<!-- 
    33 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 
     
    5858        if ( !oActiveEl ) 
    5959        { 
    60                 oActiveEl = oEditor.FCK.EditorDocument.createElement( 'FORM' ) ; 
    61                 oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ; 
    62                 oActiveEl.innerHTML = '&nbsp;' ; 
     60                oActiveEl = oEditor.FCK.InsertElement( 'form' ) ; 
     61 
     62                if ( oEditor.FCKBrowserInfo.IsGeckoLike ) 
     63                        oActiveEl.innerHTML = GECKO_BOGUS ; 
    6364        } 
    6465 
    6566        oActiveEl.name = GetE('txtName').value ; 
    66         SetAttribute( oActiveEl, 'action'       , GetE('txtAction').value ) ; 
     67        SetAttribute( oActiveEl, 'action', GetE('txtAction').value ) ; 
    6768        oActiveEl.method = GetE('txtMethod').value ; 
    6869 
  • FCKeditor/trunk/editor/dialog/fck_hiddenfield.html

    r202 r308  
    8080                oFakeImage      = oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__InputHidden', oActiveEl ) ; 
    8181                oFakeImage.setAttribute( '_fckinputhidden', 'true', 0 ) ; 
    82                 oFakeImage      = FCK.InsertElementAndGetIt( oFakeImage ) ; 
     82                oFakeImage      = FCK.InsertElement( oFakeImage ) ; 
    8383        } 
    8484        else 
  • FCKeditor/trunk/editor/dialog/fck_image/fck_image.js

    r281 r308  
    221221                if ( bImageButton ) 
    222222                { 
    223                         oImage = FCK.EditorDocument.createElement( 'INPUT' ) ; 
     223                        oImage = FCK.EditorDocument.createElement( 'input' ) ; 
    224224                        oImage.type = 'image' ; 
    225                         oImage = FCK.InsertElementAndGetIt( oImage ) ; 
     225                        oImage = FCK.InsertElement( oImage ) ; 
    226226                } 
    227227                else 
    228                         oImage = FCK.CreateElement( 'IMG' ) ; 
     228                        oImage = FCK.InsertElement( 'img' ) ; 
    229229        } 
    230230        else 
  • FCKeditor/trunk/editor/dialog/fck_link/fck_link.js

    r255 r308  
    538538 
    539539                // Create a new (empty) anchor. 
    540                 oLink = oEditor.FCK.CreateElement( 'a' ) ; 
     540                oLink = oEditor.FCK.InsertElement( 'a' ) ; 
    541541        } 
    542542 
  • FCKeditor/trunk/editor/dialog/fck_radiobutton.html

    r132 r308  
    6060                oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ; 
    6161                oActiveEl.type = 'radio' ; 
    62                 oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ; 
     62                oActiveEl = oEditor.FCK.InsertElement( oActiveEl ) ; 
    6363        } 
    6464 
  • FCKeditor/trunk/editor/dialog/fck_select.html

    r132 r308  
    7979 
    8080        if ( !oActiveEl ) 
    81         { 
    82                 oActiveEl = oEditor.FCK.EditorDocument.createElement( 'SELECT' ) ; 
    83                 oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ; 
    84         } 
     81                oActiveEl = oEditor.FCK.InsertElement( 'select' ) ; 
    8582 
    8683        SetAttribute( oActiveEl, 'name' , GetE('txtName').value ) ; 
  • FCKeditor/trunk/editor/dialog/fck_smiley.html

    r132 r308  
    4646function InsertSmiley( url ) 
    4747{ 
    48         var oImg = oEditor.FCK.CreateElement( 'IMG' ) ; 
     48        var oImg = oEditor.FCK.InsertElement( 'img' ) ; 
    4949        oImg.src = url ; 
    5050        oImg.setAttribute( '_fcksavedurl', url ) ; 
  • FCKeditor/trunk/editor/dialog/fck_textarea.html

    r132 r308  
    5757{ 
    5858        if ( !oActiveEl ) 
    59         { 
    60                 oActiveEl = oEditor.FCK.EditorDocument.createElement( 'TEXTAREA' ) ; 
    61                 oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ; 
    62         } 
     59                oActiveEl = oEditor.FCK.InsertElement( 'textarea' ) ; 
    6360 
    6461        oActiveEl.name = GetE('txtName').value ; 
  • FCKeditor/trunk/editor/dialog/fck_textfield.html

    r132 r308  
    7777                oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ; 
    7878                oActiveEl.type = GetE('txtType').value ; 
    79                 oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ; 
     79                oActiveEl = oEditor.FCK.InsertElement( oActiveEl ) ; 
    8080        } 
    8181 
  • FCKeditor/trunk/editor/plugins/placeholder/fckplugin.js

    r132 r308  
    3838FCKPlaceholders.Add = function( name ) 
    3939{ 
    40         var oSpan = FCK.CreateElement( 'SPAN' ) ; 
     40        var oSpan = FCK.InsertElement( 'span' ) ; 
    4141        this.SetupSpan( oSpan, name ) ; 
    4242} 
  • FCKeditor/trunk/editor/_source/classes/fckdomrange.js

    r207 r308  
    181181 
    182182                var bIsEndOfBlock = oTestRange.CheckIsCollapsed() ; 
    183                  
     183 
    184184                if ( !bIsEndOfBlock ) 
    185185                { 
     
    188188                        oTestRange._Range.cloneContents().AppendTo( eToolDiv ) ; 
    189189                        FCKDomTools.TrimNode( eToolDiv, true ) ; 
    190                          
     190 
    191191                        // Find out if we are in an empty tree of inline elements, like <b><i><span></span></i></b> 
    192192                        bIsEndOfBlock = true ; 
     
    206206                        } 
    207207                } 
    208                  
     208 
    209209                oTestRange.Release() ; 
    210210 
     
    273273                else 
    274274                        this.Collapse( true ) ; 
     275 
     276                this._UpdateElementInfo() ; 
     277        }, 
     278 
     279        MoveToPosition : function( targetElement, position ) 
     280        { 
     281                this.SetStart( targetElement, position ) ; 
     282                this.Collapse( true ) ; 
    275283        }, 
    276284 
     
    442450        }, 
    443451 
     452        SplitBlock : function() 
     453        { 
     454                if ( !this._Range ) 
     455                        this.MoveToSelection() ; 
     456 
     457                // The selection boundaries must be in the same "block limit" element. 
     458                if ( this.StartBlockLimit == this.EndBlockLimit ) 
     459                { 
     460                        // Get the current blocks. 
     461                        var eStartBlock         = this.StartBlock ; 
     462                        var eEndBlock           = this.EndBlock ; 
     463 
     464                        if ( FCKConfig.EnterMode != 'br' ) 
     465                        { 
     466                                if ( !eStartBlock ) 
     467                                { 
     468                                        eStartBlock = this._FixBlock( true ) ; 
     469                                        eEndBlock       = this.EndBlock ;       // _FixBlock may have fixed the EndBlock too. 
     470                                } 
     471 
     472                                if ( !eEndBlock ) 
     473                                        eEndBlock = this._FixBlock( false ) ; 
     474                        } 
     475 
     476                        var bIsStartOfBlock     = ( eStartBlock != null && this.CheckStartOfBlock() ) ; 
     477                        var bIsEndOfBlock       = ( eEndBlock != null && this.CheckEndOfBlock() ) ; 
     478 
     479                        // Delete the current selection. 
     480                        if ( !this.CheckIsEmpty() ) 
     481                                this.DeleteContents() ; 
     482 
     483                        if ( eStartBlock && eEndBlock &&  eStartBlock == eEndBlock ) 
     484                        { 
     485                                if ( bIsStartOfBlock ) 
     486                                { 
     487                                        this.MoveToPosition( eStartBlock, 3 ) ; 
     488                                        eStartBlock = null ; 
     489                                } 
     490                                else if ( bIsEndOfBlock ) 
     491                                { 
     492                                        this.MoveToPosition( eEndBlock, 4 ) ; 
     493                                        eEndBlock = null ; 
     494                                } 
     495                                else 
     496                                { 
     497                                        // Extract the contents of the block from the selection point to the end of its contents. 
     498                                        this.SetEnd( eStartBlock, 2 ) ; 
     499                                        var eDocFrag = this.ExtractContents() ; 
     500                                        FCKDomTools.TrimNode( eDocFrag.RootNode ) ; 
     501 
     502                                        // Duplicate the block element after it. 
     503                                        eEndBlock = eStartBlock.cloneNode( false ) ; 
     504 
     505                                        // Place the extracted contents in the duplicated block. 
     506                                        eDocFrag.AppendTo( eEndBlock ) ; 
     507 
     508                                        FCKDomTools.InsertAfterNode( eStartBlock, eEndBlock ) ; 
     509 
     510                                        this.MoveToPosition( eStartBlock, 4 ) ; 
     511                                } 
     512                        } 
     513 
     514                        if ( FCKBrowserInfo.IsGecko ) 
     515                        { 
     516                                // In Gecko, the last child node must be a bogus <br>. 
     517                                FCKTools.AppendBogusBr( eStartBlock ) ; 
     518                                FCKTools.AppendBogusBr( eEndBlock ) ; 
     519                        } 
     520 
     521                        return { 
     522                                PreviousBlock   : eStartBlock, 
     523                                NextBlock               : eEndBlock, 
     524                                WasStartOfBlock : bIsStartOfBlock, 
     525                                WasEndOfBlock   : bIsEndOfBlock 
     526                        } ; 
     527                } 
     528 
     529                return null ; 
     530        }, 
     531 
     532        // Transform a block without a block tag in a valid block (orphan text in the body or td, usually). 
     533        _FixBlock : function( isStart ) 
     534        { 
     535                // Bookmark the range so we can restore it later. 
     536                var oBookmark = this.CreateBookmark() ; 
     537 
     538                // Collapse the range to the requested ending boundary. 
     539                this.Collapse( isStart ) ; 
     540 
     541                // Expands it to the block contents. 
     542                this.Expand( 'block_contents' ) ; 
     543 
     544                // Create the fixed block. 
     545                var oFixedBlock = this.Window.document.createElement( FCKConfig.EnterMode ) ; 
     546 
     547                // Move the contents of the temporary range to the fixed block. 
     548                this.ExtractContents().AppendTo( oFixedBlock ) ; 
     549                FCKDomTools.TrimNode( oFixedBlock ) ; 
     550 
     551                // Insert the fixed block into the DOM. 
     552                this.InsertNode( oFixedBlock ) ; 
     553 
     554                // Move the range back to the bookmarked place. 
     555                this.MoveToBookmark( oBookmark ) ; 
     556 
     557                return oFixedBlock ; 
     558        }, 
     559 
    444560        Release : function( preserveWindow ) 
    445561        { 
  • FCKeditor/trunk/editor/_source/classes/fckenterkey.js

    r218 r308  
    285285        var oRange = range || new FCKDomRange( this.Window ) ; 
    286286 
    287         // If we don't have a range, move it to the selection. 
    288         if ( !range ) 
    289                 oRange.MoveToSelection() ; 
    290  
    291         // The selection boundaries must be in the same "block limit" element. 
    292         if ( oRange.StartBlockLimit == oRange.EndBlockLimit ) 
    293         { 
    294                 // If the StartBlock or EndBlock are not available (for text without a 
    295                 // block tag), we must fix them, by moving the text to a block. 
    296                 if ( !oRange.StartBlock ) 
    297                         this._FixBlock( oRange, true, blockTag ) ; 
    298  
    299                 if ( !oRange.EndBlock ) 
    300                         this._FixBlock( oRange, false, blockTag ) ; 
    301  
     287        var oSplitInfo = oRange.SplitBlock() ; 
     288 
     289        if ( oSplitInfo ) 
     290        { 
    302291                // Get the current blocks. 
    303                 var eStartBlock = oRange.StartBlock ; 
    304                 var eEndBlock   = oRange.EndBlock ; 
    305  
    306                 // Delete the current selection. 
    307                 if ( !oRange.CheckIsEmpty() ) 
    308                         oRange.DeleteContents() ; 
    309  
    310                 // If the selection boundaries are in the same block element 
    311                 if ( eStartBlock == eEndBlock ) 
    312                 { 
     292                var ePreviousBlock      = oSplitInfo.PreviousBlock ; 
     293                var eNextBlock          = oSplitInfo.NextBlock ; 
     294 
     295                var bIsStartOfBlock     = oSplitInfo.WasStartOfBlock ; 
     296                var bIsEndOfBlock       = oSplitInfo.WasEndOfBlock ; 
     297 
     298                // If we have both the previous and next blocks, it means that the 
     299                // boundaries were on separated blocks, or none of them where on the 
     300                // block limits (start/end). 
     301                if ( !oSplitInfo.WasStartOfBlock && !oSplitInfo.WasEndOfBlock ) 
     302                { 
     303                        // Move the selection to the end block. 
     304                        if ( eNextBlock ) 
     305                                oRange.MoveToElementEditStart( eNextBlock ) ; 
     306                } 
     307                else 
     308                { 
     309                        if ( bIsStartOfBlock && bIsEndOfBlock && eNextBlock.tagName.toUpperCase() == 'LI' ) 
     310                        { 
     311                                oRange.MoveToElementStart( eNextBlock ) ; 
     312                                this._OutdentWithSelection( eNextBlock, oRange ) ; 
     313                                oRange.Release() ; 
     314                                return true ; 
     315                        } 
     316 
    313317                        var eNewBlock ; 
    314318 
    315                         var bIsStartOfBlock     = oRange.CheckStartOfBlock() ; 
    316                         var bIsEndOfBlock       = oRange.CheckEndOfBlock() ; 
    317  
    318                         if ( bIsStartOfBlock && !bIsEndOfBlock ) 
    319                         { 
    320                                 eNewBlock = eStartBlock.cloneNode(false) ; 
    321  
    322                                 if ( FCKBrowserInfo.IsGeckoLike ) 
    323                                         eNewBlock.innerHTML = GECKO_BOGUS ; 
    324  
    325                                 // Place the new block before the current block element. 
    326                                 eStartBlock.parentNode.insertBefore( eNewBlock, eStartBlock ) ; 
    327  
    328                                 // This is tricky, but to make the new block visible correctly 
    329                                 // we must select it. 
    330                                 if ( FCKBrowserInfo.IsIE ) 
    331                                 { 
    332                                         // Move the selection to the new block. 
    333                                         oRange.MoveToNodeContents( eNewBlock ) ; 
    334  
    335                                         oRange.Select() ; 
    336                                 } 
    337  
    338                                 // Move the selection to the new block. 
    339                                 oRange.MoveToElementEditStart( eStartBlock ) ; 
    340                         } 
    341                         else 
    342                         { 
    343                                 // Check if the selection is at the end of the block. 
    344                                 if ( bIsEndOfBlock ) 
    345                                 { 
    346                                         var sStartBlockTag = eStartBlock.tagName.toUpperCase() ; 
    347  
    348                                         // If the entire block is selected, and we are in a LI, let's decrease its indentation. 
    349                                         if ( bIsStartOfBlock && sStartBlockTag == 'LI' ) 
    350                                         { 
    351                                                 this._OutdentWithSelection( eStartBlock, oRange ) ; 
    352                                                 oRange.Release() ; 
    353                                                 return true ; 
    354                                         } 
    355                                         else 
    356                                         { 
    357                                                 // If is a header tag, or we are in a Shift+Enter (#77), 
    358                                                 // create a new block element. 
    359                                                 if ( (/^H[1-6]$/).test( sStartBlockTag ) || this._HasShift ) 
    360                                                         eNewBlock = this.Window.document.createElement( blockTag ) ; 
    361                                                 // Otherwise, duplicate the current block. 
    362                                                 else 
    363                                                 { 
    364                                                         eNewBlock = eStartBlock.cloneNode(false) ; 
    365                                                         this._RecreateEndingTree( eStartBlock, eNewBlock ) ; 
    366                                                 } 
    367  
    368                                                 if ( FCKBrowserInfo.IsGeckoLike ) 
    369                                                 { 
    370                                                         eNewBlock.innerHTML = GECKO_BOGUS ; 
    371  
    372                                                         // If the entire block is selected, let's add a bogus in the start block. 
    373                                                         if ( bIsStartOfBlock ) 
    374                                                                 eStartBlock.innerHTML = GECKO_BOGUS ; 
    375                                                 } 
    376                                         } 
    377                                 } 
     319                        if ( ePreviousBlock ) 
     320                        { 
     321                                var sPreviousBlockTag = ePreviousBlock.tagName.toUpperCase() ; 
     322 
     323                                // If is a header tag, or we are in a Shift+Enter (#77), 
     324                                // create a new block element. 
     325                                if ( this._HasShift || (/^H[1-6]$/).test( sPreviousBlockTag ) ) 
     326                                        eNewBlock = this.Window.document.createElement( blockTag ) ; 
    378327                                else 
    379328                                { 
    380                                         // Extract the contents of the block from the selection point to the end of its contents. 
    381                                         oRange.SetEnd( eStartBlock, 2 ) ; 
    382                                         var eDocFrag = oRange.ExtractContents() ; 
    383  
    384                                         // Duplicate the block element after it. 
    385                                         eNewBlock = eStartBlock.cloneNode(false) ; 
    386  
    387                                         // It could be that we are in a LI with a child UL/OL. Insert a bogus to give us space to type. 
    388                                         FCKDomTools.TrimNode( eDocFrag.RootNode ) ; 
    389                                         if ( eDocFrag.RootNode.firstChild.nodeType == 1 && eDocFrag.RootNode.firstChild.tagName.toUpperCase().Equals( 'UL', 'OL' ) ) 
    390                                                 eNewBlock.innerHTML = GECKO_BOGUS ; 
    391  
    392                                         // Place the extracted contents in the duplicated block. 
    393                                         eDocFrag.AppendTo( eNewBlock ) ; 
    394  
    395                                         if ( FCKBrowserInfo.IsGecko ) 
    396                                         { 
    397                                                 // In Gecko, the last child node must be a bogus <br>. 
    398                                                 this._AppendBogusBr( eStartBlock ) ; 
    399                                                 this._AppendBogusBr( eNewBlock ) ; 
    400                                         } 
     329                                        // Otherwise, duplicate the previous block. 
     330                                        eNewBlock = ePreviousBlock.cloneNode( false ) ; 
     331                                        this._RecreateEndingTree( ePreviousBlock, eNewBlock ) ; 
    401332                                } 
    402  
    403                                 if ( eNewBlock ) 
    404                                 { 
    405                                         FCKDomTools.InsertAfterNode( eStartBlock, eNewBlock ) ; 
    406  
    407                                         // Move the selection to the new block. 
    408                                         oRange.MoveToElementEditStart( eNewBlock ) ; 
    409  
    410                                         if ( FCKBrowserInfo.IsGecko ) 
    411                                                 eNewBlock.scrollIntoView( false ) ; 
    412                                 } 
    413