Make WordPress Core

Ticket #31412: 31412.19.patch

File 31412.19.patch, 7.9 KB (added by iseulde, 10 years ago)
  • src/wp-includes/js/mce-view.js

     
    6464                 * Returns the settings of a view type.
    6565                 *
    6666                 * @param {String} type The view type.
     67                 *
     68                 * @return {Function} The view constructor.
    6769                 */
    6870                get: function( type ) {
    6971                        return views[ type ];
     
    142144                 * @param {String} type    The view type.
    143145                 * @param {String} text    The textual representation of the view.
    144146                 * @param {Object} options Options.
     147                 *
     148                 * @return {wp.mce.View} The view instance.
    145149                 */
    146150                createInstance: function( type, text, options ) {
    147151                        var View = this.get( type ),
     
    163167                /**
    164168                 * Get a view instance.
    165169                 *
    166                  * @param {String} text The textual representation of the view.
     170                 * @param {(String|HTMLElement)} object The textual representation of the view or the view node.
     171                 *
     172                 * @return {wp.mce.View} The view instance.
     173                 */
     174                getInstance: function( object ) {
     175                        if ( typeof object === 'string' ) {
     176                                return instances[ encodeURIComponent( object ) ];
     177                        }
     178
     179                        return instances[ $( object ).data( 'wpview-text' ) ];
     180                },
     181
     182                /**
     183                 * Given a view node, get the view's text.
     184                 *
     185                 * @param {HTMLElement} node The view node.
     186                 *
     187                 * @return {String} The textual representation of the view.
    167188                 */
    168                 getInstance: function( text ) {
    169                         return instances[ encodeURIComponent( text ) ];
     189                getText: function( node ) {
     190                        return decodeURIComponent( $( node ).data( 'wpview-text' ) || '' );
    170191                },
    171192
    172193                /**
     
    188209                 * @param {HTMLElement}    node   The view node to update.
    189210                 */
    190211                update: function( text, editor, node ) {
    191                         var oldText = decodeURIComponent( $( node ).data( 'wpview-text' ) ),
    192                                 instance = this.getInstance( oldText );
     212                        var instance = this.getInstance( node );
    193213
    194214                        if ( instance ) {
    195215                                instance.update( text, editor, node );
     
    203223                 * @param {HTMLElement}    node   The view node to edit.
    204224                 */
    205225                edit: function( editor, node ) {
    206                         var text = decodeURIComponent( $( node ).data( 'wpview-text' ) ),
    207                                 instance = this.getInstance( text );
     226                        var instance = this.getInstance( node );
    208227
    209228                        if ( instance && instance.edit ) {
    210                                 instance.edit( text, function( text ) {
     229                                instance.edit( instance.text, function( text ) {
    211230                                        instance.update( text, editor, node );
    212231                                } );
    213232                        }
     233                },
     234
     235                /**
     236                 * Remove a given view node from the DOM.
     237                 *
     238                 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
     239                 * @param {HTMLElement}    node   The view node to remove.
     240                 */
     241                remove: function( editor, node ) {
     242                        var instance = this.getInstance( node );
     243
     244                        if ( instance ) {
     245                                instance.remove( editor, node );
     246                        }
    214247                }
    215248        };
    216249
     
    218251         * A Backbone-like View constructor intended for use when rendering a TinyMCE View.
    219252         * The main difference is that the TinyMCE View is not tied to a particular DOM node.
    220253         *
    221          * @param {Object} Options.
     254         * @param {Object} options Options.
    222255         */
    223256        wp.mce.View = function( options ) {
    224257                _.extend( this, options );
     
    276309
    277310                        if ( this.getContent() ) {
    278311                                this.setContent( this.getContent(), function( editor, node ) {
    279                                         $( node ).data( 'rendered', true );
    280                                         this.bindNodes.apply( this, arguments );
     312                                        $( node ).data( 'rendered', true ).trigger( 'wp-mce-view-bind' );
    281313                                }, force ? null : false );
    282314                        } else {
    283315                                this.setLoader();
     
    285317                },
    286318
    287319                /**
    288                  * Binds a given rendered view node.
    289                  * Runs after a view node's content is added to the DOM.
    290                  *
    291                  * @param {tinymce.Editor} editor      The TinyMCE editor instance the view node is in.
    292                  * @param {HTMLElement}    node        The view node.
    293                  * @param {HTMLElement}    contentNode The view's content node.
    294                  */
    295                 bindNodes: function( /* editor, node, contentNode */ ) {},
    296 
    297                 /**
    298320                 * Unbinds all view nodes tied to this view instance.
    299321                 * Runs before their content is removed from the DOM.
    300322                 */
    301323                unbind: function() {
    302                         this.getNodes( function() {
    303                                 this.unbindNodes.apply( this, arguments );
     324                        this.getNodes( function( editor, node ) {
     325                                $( node ).trigger( 'wp-mce-view-unbind' );
    304326                        }, true );
    305327                },
    306328
    307329                /**
    308                  * Unbinds a given view node.
    309                  * Runs before the view node's content is removed from the DOM.
    310                  *
    311                  * @param {tinymce.Editor} editor      The TinyMCE editor instance the view node is in.
    312                  * @param {HTMLElement}    node        The view node.
    313                  * @param {HTMLElement}    contentNode The view's content node.
    314                  */
    315                 unbindNodes: function( /* editor, node, contentNode */ ) {},
    316 
    317                 /**
    318330                 * Gets all the TinyMCE editor instances that support views.
    319331                 *
    320332                 * @param {Function} callback A callback.
     
    378390                 */
    379391                replaceMarkers: function() {
    380392                        this.getMarkers( function( editor, node ) {
    381                                 if ( $( node ).text() !== this.text ) {
     393                                if ( $( node ).html() !== this.text ) {
    382394                                        editor.dom.setAttrib( node, 'data-wpview-marker', null );
    383395                                        return;
    384396                                }
     
    455467                                var dom = editor.dom,
    456468                                        styles = '',
    457469                                        bodyClasses = editor.getBody().className || '',
    458                                         iframe, iframeDoc, i, resize;
     470                                        iframe, iframeDoc, observer, i, resize;
    459471
    460472                                content.innerHTML = '';
    461473                                head = head || '';
     
    547559                                        };
    548560
    549561                                        if ( MutationObserver ) {
    550                                                 new MutationObserver( _.debounce( function() {
     562                                                observer = new MutationObserver( _.debounce( function() {
    551563                                                        resize();
    552                                                 }, 100 ) )
    553                                                 .observe( iframeDoc.body, {
     564                                                }, 100 ) );
     565
     566                                                observer.observe( iframeDoc.body, {
    554567                                                        attributes: true,
    555568                                                        childList: true,
    556569                                                        subtree: true
     
    561574                                                }
    562575                                        }
    563576
     577                                        function classChange() {
     578                                                iframeDoc.body.className = editor.getBody().className;
     579                                        }
     580
    564581                                        if ( importStyles ) {
    565                                                 editor.on( 'wp-body-class-change', function() {
    566                                                         iframeDoc.body.className = editor.getBody().className;
    567                                                 } );
     582                                                editor.on( 'wp-body-class-change', classChange );
    568583                                        }
     584
     585                                        $( node ).one( 'wp-mce-view-unbind', function() {
     586                                                observer.disconnect();
     587                                                editor.off( 'wp-body-class-change', classChange );
     588                                        } );
    569589                                }, 50 );
    570590
    571591                                callback && callback.apply( this, arguments );
     
    631651                        $( node ).data( 'rendered', false );
    632652                        editor.dom.setAttrib( node, 'data-wpview-text', encodeURIComponent( text ) );
    633653                        wp.mce.views.createInstance( this.type, text, this.match( text ).options ).render();
     654                },
     655
     656                /**
     657                 * Remove a given view node from the DOM.
     658                 *
     659                 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
     660                 * @param {HTMLElement}    node   The view node to remove.
     661                 */
     662                remove: function( editor, node ) {
     663                        $( node ).trigger( 'wp-mce-view-unbind' );
     664                        editor.dom.remove( node );
    634665                }
    635666        } );
    636667} )( window, window.wp, window.jQuery );
     
    662693                        frame.on( 'close', function() {
    663694                                frame.detach();
    664695                        } );
     696
     697                        frame.open();
    665698                }
    666699        };
    667700
  • src/wp-includes/js/tinymce/plugins/wpview/plugin.js

     
    7272        }
    7373
    7474        function removeView( view ) {
    75                 // TODO: trigger an event to run a clean up function.
    76                 // Maybe `jQuery( view ).trigger( 'remove' );`?
    7775                editor.undoManager.transact( function() {
    7876                        handleEnter( view );
    79                         editor.dom.remove( view );
     77                        wp.mce.views.remove( editor, view );
    8078                });
    8179        }
    8280
     
    107105                clipboard = dom.create( 'div', {
    108106                        'class': 'wpview-clipboard',
    109107                        'contenteditable': 'true'
    110                 }, decodeURIComponent( editor.dom.getAttrib( viewNode, 'data-wpview-text' ) ) );
     108                }, wp.mce.views.getText( viewNode ) );
    111109
    112110                editor.dom.select( '.wpview-body', viewNode )[0].appendChild( clipboard );
    113111