Make WordPress Core

Changeset 22210


Ignore:
Timestamp:
10/12/2012 03:28:22 AM (14 years ago)
Author:
koopersmith
Message:

MCE Views: First pass at keystroke and insertion handling.

  • When a MCE view is selected, normal keystrokes (those without command/control) are blocked.
  • Backspace/delete will successfully remove the view.
  • Arrow handling will be added at a later point.
  • When a MCE view is selected and content is pasted or injected (e.g. when an attachment is added), the content is added to the first text node after the view. If the view is at the end of the document or the next element is another view, a text node is injected into the DOM immediately after the selected view.

see #21390, #21812, #21813, #21815.

Location:
trunk/wp-includes/js
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/js/mce-view.js

    r22208 r22210  
    312312                        $( '.wp-view-wrap', scope ).each( function() {
    313313                                var wrapper = $(this),
    314                                         id = wrapper.data('wp-view'),
    315                                         view = instances[ id ];
     314                                        view = wp.mce.view.instance( this );
    316315
    317316                                if ( ! view )
     
    358357                attrs: function( content ) {
    359358                        return wp.mce.view.removeInternalAttrs( wp.html.attrs( content ) );
     359                },
     360
     361                // ### instance( scope )
     362                //
     363                // Accepts a MCE view wrapper `node` (i.e. a node with the
     364                // `wp-view-wrap` class).
     365                instance: function( node ) {
     366                        var id = $( node ).data('wp-view');
     367
     368                        if ( id )
     369                                return instances[ id ];
    360370                },
    361371
  • trunk/wp-includes/js/tinymce/plugins/wpview/editor_plugin_src.js

    r22208 r22210  
    44
    55(function() {
    6 
     6        var VK = tinymce.VK,
     7                TreeWalker = tinymce.dom.TreeWalker,
     8                selected;
    79
    810        tinymce.create('tinymce.plugins.wpView', {
    911                init : function( editor, url ) {
    10                         var wpView = this,
    11                                 selected;
     12                        var wpView = this;
    1213
    1314                        // Check if the `wp.mce` API exists.
     
    3940                        editor.onInit.add( function( editor ) {
    4041
     42                                // When a view is selected, ensure content that is being pasted
     43                                // or inserted is added to a text node (instead of the view).
     44                                editor.selection.onBeforeSetContent.add( function( selection, o ) {
     45                                        var view = wpView.getParentView( selection.getNode() ),
     46                                                walker, target;
     47
     48                                        // If the selection is not within a view, bail.
     49                                        if ( ! view )
     50                                                return;
     51
     52                                        // If there are no additional nodes or the next node is a
     53                                        // view, create a text node after the current view.
     54                                        if ( ! view.nextSibling || wpView.isView( view.nextSibling ) ) {
     55                                                target = editor.getDoc().createTextNode('');
     56                                                editor.dom.insertAfter( target, view );
     57
     58                                        // Otherwise, find the next text node.
     59                                        } else {
     60                                                walker = new TreeWalker( view.nextSibling, view.nextSibling );
     61                                                target = walker.next();
     62                                        }
     63
     64                                        // Select the `target` text node.
     65                                        selection.select( target );
     66                                        selection.collapse( true );
     67                                });
     68
    4169                                // When the selection's content changes, scan any new content
    4270                                // for matching views and immediately render them.
     
    6795
    6896                        // Triggers when the selection is changed.
    69                         editor.onNodeChange.add( function( editor, controlManager, node, collapsed, o ) {
     97                        // Add the event handler to the top of the stack.
     98                        editor.onNodeChange.addToTop( function( editor, controlManager, node, collapsed, o ) {
    7099                                var view = wpView.getParentView( node );
    71100
     101                                // Update the selected view.
     102                                if ( view ) {
     103                                        wpView.select( view );
     104
     105                                        // Prevent the selection from propagating to other plugins.
     106                                        return false;
     107
    72108                                // If we've clicked off of the selected view, deselect it.
    73                                 if ( selected && selected !== view )
    74                                         wp.mce.view.deselect( selected );
     109                                } else {
     110                                        wpView.deselect();
     111                                }
     112                        });
    75113
    76                                 // Bail if we're not selecting another view.
    77                                 if ( ! view )
     114                        editor.onKeyDown.addToTop( function( editor, event ) {
     115                                var keyCode = event.keyCode,
     116                                        view, instance;
     117
     118                                // If a view isn't selected, let the event go on its merry way.
     119                                if ( ! selected )
    78120                                        return;
    79121
    80                                 // Update the selected view.
    81                                 selected = view;
    82                                 wp.mce.view.select( selected );
     122                                // If the caret is not within the selected view, deselect the
     123                                // view and bail.
     124                                view = wpView.getParentView( editor.selection.getNode() );
     125                                if ( view !== selected ) {
     126                                        wpView.deselect();
     127                                        return;
     128                                }
    83129
    84                                 // Prevent the selection from propagating to other plugins.
    85                                 return false;
     130                                // If delete or backspace is pressed, delete the view.
     131                                if ( keyCode === VK.DELETE || keyCode === VK.BACKSPACE ) {
     132                                        if ( (instance = wp.mce.view.instance( selected )) ) {
     133                                                instance.remove();
     134                                                wpView.deselect();
     135                                        }
     136                                }
     137
     138                                // Let keypresses that involve the command or control keys through.
     139                                // Also, let any of the F# keys through.
     140                                if ( event.metaKey || event.ctrlKey || ( keyCode >= 112 && keyCode <= 123 ) )
     141                                        return;
     142
     143                                event.preventDefault();
    86144                        });
    87145                },
     
    89147                getParentView : function( node ) {
    90148                        while ( node ) {
    91                                 if ( /(?:^|\s)wp-view-wrap(?:\s|$)/.test( node.className ) )
     149                                if ( this.isView( node ) )
    92150                                        return node;
    93151
    94152                                node = node.parentNode;
    95153                        }
     154                },
     155
     156                isView : function( node ) {
     157                        return (/(?:^|\s)wp-view-wrap(?:\s|$)/).test( node.className );
     158                },
     159
     160                select : function( view ) {
     161                        if ( view === selected )
     162                                return;
     163
     164                        this.deselect();
     165                        selected = view;
     166                        wp.mce.view.select( selected );
     167                },
     168
     169                deselect : function() {
     170                        if ( selected )
     171                                wp.mce.view.deselect( selected );
     172                        selected = null;
    96173                },
    97174
Note: See TracChangeset for help on using the changeset viewer.