Ticket #4548: 4548_5.patch

File 4548_5.patch, 9.1 KB (added by Garry Yao, 9 years ago)
  • _source/plugins/drupalpagebreak/plugin.js

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6/**
     7 * @file Plugin for creating Drupal teasers(fake object).
     8 */
     9CKEDITOR.plugins.add( 'drupalpagebreak',
     10{
     11        requires  : [ 'htmldataprocessor','fakeobjects', 'styles' ],
     12        init : function( editor )
     13        {
     14                // Add the style that renders our placeholder.
     15                editor.addCss(
     16                        'img.cke_drupal_break' +
     17                        '{' +
     18                                'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/placeholder.gif' ) + ');' +
     19                            '-webkit-background-size: 20px 20px;' +
     20                            '-o-background-size: 20px 20px;' +
     21                                'background-position: center center;' +
     22                                'background-repeat: no-repeat;' +
     23                                'display: inline;' +
     24                                'width: 20px;' +
     25                                'vertical-align: middle;' +
     26                                'border: #999999 1px dotted;' +
     27                        '}' );
     28
     29                editor.ui.addButton( 'DrupalPageBreak',
     30                        {
     31                                label : editor.lang.drupalPageBreak,
     32                                command : 'drupalpagebreak'
     33                        });
     34        },
     35
     36        // There's currently no gurantee on registration order, this make sure
     37        // the registration will come after the default ones in 'htmldataprocessor'.
     38        afterInit : function( editor )
     39        {
     40                var dataProcessor = editor.dataProcessor,
     41                        dataFilter = dataProcessor.dataFilter,
     42                        htmlFilter = dataProcessor.htmlFilter,
     43                        // Borrow the comment output filters to restore them.
     44                        commentFilters = htmlFilter._.comment,
     45                        filter = commentFilters && ( commentFilters.filter || commentFilters[ 0 ] ),
     46                        config = editor.config,
     47                        pageBreak = config.drupalPageBreak,
     48                        displayName,
     49                        allFakeWrapperTagNames = {};
     50
     51                pageBreak.displayName = displayName = pageBreak.displayName || 'drupal-page-break';
     52
     53                // Register into DTDs.
     54                var dtd = CKEDITOR.dtd,
     55                        dtdParents = pageBreak.dtdParents;
     56                for( var tag in dtdParents )
     57                {
     58                        if( dtdParents.hasOwnProperty( tag ) )
     59                        {
     60                                       
     61                                var parentDtd = tag == 'body' ? dtd.$body : dtd[ tag ];
     62                                parentDtd && ( parentDtd[ displayName ] = 1 );
     63                        }
     64                }
     65
     66                // DataFilter for creating fake objects from HTML comment.
     67                dataFilter.addRules(
     68                        {
     69                                comment : function( value )
     70                                {
     71                                        var cdata = filter( value );
     72
     73                                        // CData instance is received.
     74                                        if ( cdata.value )
     75                                        {
     76                                                var fakeElement;
     77                                                // Is it actually a comment and match the desired pattern?
     78                                                cdata.value.replace( /<!--([\s\S]*?)-->/, function( match, content )
     79                                                {
     80                                                        if( content == pageBreak.content )
     81                                                        {
     82                                                                var fakeWrapper = new CKEDITOR.htmlParser.element( displayName, {} );
     83                                                                fakeWrapper.add( cdata );
     84                                                                fakeElement = editor.createFakeParserElement(
     85                                                                                fakeWrapper,
     86                                                                                'cke_drupal_break cke_' + CKEDITOR.tools.escapeCssSelector( displayName ),
     87                                                                                displayName,
     88                                                                                false );
     89
     90                                                                // Comment content specific style.
     91                                                                fakeElement.attributes.style = CKEDITOR.style.getStyleText( pageBreak );
     92                                                                allFakeWrapperTagNames[ displayName ] = 1;
     93                                                        }
     94                                                } );
     95
     96                                                if ( fakeElement )
     97                                                {
     98                                                        return fakeElement;
     99                                                }
     100                                        }
     101                                        return value;
     102                                }
     103                        } );
     104
     105                // HtmlFilter rules for outputting as a HTML comment.
     106                var restorePageBreakRule = { elements : {} };
     107                restorePageBreakRule.elements[ displayName ] = function( wrapper )
     108                {
     109                        delete wrapper.name;
     110                }
     111                htmlFilter.addRules( restorePageBreakRule );
     112
     113                editor.addCommand( 'drupalpagebreak',
     114                {
     115                        exec : function( editor )
     116                        {
     117                                var ranges = editor.getSelection().getRanges();
     118                                for ( var range, i = 0 ; i < ranges.length ; i++ )
     119                                {
     120                                        range = ranges[ i ];
     121                                        range.deleteContents();
     122                                        var current, dtd;
     123                                        while ( ( current = range.getCommonAncestor( false, true ) )
     124                                                        && ( dtd = CKEDITOR.dtd[ current.getName( ) ] )
     125                                                        && !dtd[ displayName ] )
     126                                                range.splitBlock();
     127
     128                                        // We intend to place the cursor right at the last split
     129                                        // point for later use of editor::insertHtml, while in some
     130                                        // situation this kind of selection doesn't work (e.g. between
     131                                        // two tables in IE), so here we employ a text node as place-holder.
     132                                        var placeholder = editor.document.createText( '\xa0' ),
     133                                                next;
     134                                        range.insertNode( placeholder );
     135                                        range.select();
     136                                        next = placeholder.getNextSourceNode( true );
     137
     138                                        editor.insertHtml( '<!--' + pageBreak.content + '-->');
     139
     140                                        // Place cursor at the next editable position.
     141                                        if ( next && next.type == CKEDITOR.NODE_ELEMENT )
     142                                                range.moveToElementEditStart( next );
     143                                        else
     144                                                range.collapse();
     145
     146                                        range.select( true );
     147                                }
     148                        }
     149                } );
     150        }
     151} );
     152
     153/**
     154 * A list of comment definition which will be converted to fake element in wysiwyg mode.
     155 * @name CKEDITOR.config.fakeComments
     156 * @type Array
     157 * @default []
     158 * @example
     159 * CKEDITOR.config.drupalPageBreak =
     160 * {
     161 *              content : 'pagebreak',
     162 *              styles :
     163 *              {
     164 *                      display : 'block'
     165 *              },
     166 *              dtdParents : CKEDITOR.dtd.$block,    // List of of valid parent element tag names,
     167 *                                              // could impact on the position how fake object
     168 *                                              // is positioned in document.
     169 *              displayName : 'page-break'
     170 * };
     171 */
  • _source/core/dom/elementpath.js

     
    99        var pathBlockElements = { address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,li:1,dt:1,de:1 };
    1010
    1111        // Elements that may be considered the "Block limit" in an element path.
    12         var pathBlockLimitElements = { body:1,div:1,table:1,tbody:1,tr:1,td:1,th:1,caption:1,form:1 };
     12        var pathBlockLimitElements = { body:1,div:1,table:1,tbody:1,tr:1,td:1,th:1,caption:1,form:1,ul:1,ol:1,dl:1 };
    1313
    1414        // Check if an element contains any block element.
    1515        var checkHasBlock = function( element )
  • _source/core/dom/range.js

     
    14051405                        return fixedBlock;
    14061406                },
    14071407
     1408                /**
     1409                 * Remove the contents of the range, and split the then occupied
     1410                 * block into two, while setup the new position between them.
     1411                 * Note: If the range is not currently within a block, the result will
     1412                 *  depend on the {@param blockTag }
     1413                 *  1. Establish one new block element of the specified tag name before split;
     1414                 *  2. Just split up the surrounding blockLimit element unless it's already inside <body>.
     1415                 * @param {String} blockTag The tag name
     1416                 */
    14081417                splitBlock : function( blockTag )
    14091418                {
    14101419                        var startPath   = new CKEDITOR.dom.elementPath( this.startContainer ),
     
    14131422                        var startBlockLimit     = startPath.blockLimit,
    14141423                                endBlockLimit   = endPath.blockLimit;
    14151424
    1416                         var startBlock  = startPath.block,
    1417                                 endBlock        = endPath.block;
     1425                        var startBlock  = startPath.block || !blockTag && startBlockLimit,
     1426                                endBlock        = endPath.block || !blockTag && endBlockLimit;
    14181427
    14191428                        var elementPath = null;
     1429
    14201430                        // Do nothing if the boundaries are in different block limits.
    1421                         if ( !startBlockLimit.equals( endBlockLimit ) )
     1431                        if ( blockTag && !startBlockLimit.equals( endBlockLimit ) )
    14221432                                return null;
     1433                        // Don't split <body>.
     1434                        else if( !blockTag && ( startBlock.is( 'body' ) || endBlock.is( 'body' ) ) )
     1435                                return null;
    14231436
    14241437                        // Get or fix current blocks.
    14251438                        if ( blockTag != 'br' )
     
    14731486
    14741487                                        // In Gecko, the last child node must be a bogus <br>.
    14751488                                        // Note: bogus <br> added under <ul> or <ol> would cause
    1476                                         // lists to be incorrectly rendered.
    1477                                         if ( !CKEDITOR.env.ie && !startBlock.is( 'ul', 'ol') )
    1478                                                 startBlock.appendBogus() ;
    1479                                 }
    1480                         }
     1489                                        // lists to be incorrectly rendered, and <br> under <tr>
     1490                                        // or <tbody> will bring inconsistency output among browsers.
     1491                                        if ( !CKEDITOR.env.ie )
     1492                                        {
     1493                                                var dtd = CKEDITOR.dtd[ startBlock.getName() ];
     1494                                                dtd[ 'br' ] && startBlock.appendBogus() ;
     1495                                        }
     1496                                }
     1497                        }
    14811498
    14821499                        return {
    14831500                                previousBlock : startBlock,
  • _source/core/htmlparser/fragment.js

     
    345345
    346346                        checkPending();
    347347
    348                         if ( fixForBody && !currentNode.type )
     348                        if ( fixForBody && CKEDITOR.tools.trim( text ) && !currentNode.type )
    349349                                this.onTagOpen( fixForBody, {} );
    350350
    351351                        // Shrinking consequential spaces into one single for all elements
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy