WordPress.org

Make WordPress Core

Changeset 27632


Ignore:
Timestamp:
03/20/2014 02:47:15 AM (6 years ago)
Author:
azaozz
Message:

wpView: select/deselect views when moving the caret with the arrow keys, don't move the caret after deselect(), props gcorne, see #26959

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/js/tinymce/plugins/wpview/plugin.js

    r27582 r27632  
    110110            dom.unbind( selected, 'beforedeactivate focusin focusout click mouseup', _stop );
    111111            dom.removeClass( selected, 'selected' );
    112 
    113             editor.selection.select( selected.nextSibling );
    114             editor.selection.collapse();
    115 
    116112        }
    117113
    118114        selected = null;
     115    }
     116
     117    function selectSiblingView( node, direction ) {
     118        var body = editor.getBody(),
     119            sibling = direction === 'previous' ? 'previousSibling' : 'nextSibling';
     120
     121        while ( node && node.parentNode !== body ) {
     122            if ( node[sibling] ) {
     123                // The caret will be in another element
     124                return false;
     125            }
     126
     127            node = node.parentNode;
     128        }
     129
     130        if ( isView( node[sibling] ) ) {
     131            select( node[sibling] );
     132            return true;
     133        }
     134
     135        return false;
    119136    }
    120137
     
    177194            y = event.clientY;
    178195
     196            // Detect clicks above or to the left if the first node is a wpview
    179197            if ( isView( firstNode ) && ( ( x < firstNode.offsetLeft && y < ( firstNode.offsetHeight - scrollTop ) ) ||
    180198                y < firstNode.offsetTop ) ) {
    181                 // detect events above or to the left of the first view
    182199
    183200                padNode = createPadNode();
    184201                body.insertBefore( padNode, firstNode );
     202
     203            // Detect clicks to the right and below the last view
    185204            } else if ( isView( lastNode ) && ( x > ( lastNode.offsetLeft + lastNode.offsetWidth ) ||
    186205                ( ( scrollTop + y ) - ( lastNode.offsetTop + lastNode.offsetHeight ) ) > 0 ) ) {
    187                 // detect events to the right and below the last view
    188206
    189207                padNode = createPadNode();
     
    254272                event.stopPropagation();
    255273
    256                 if ( event.type === 'click' ) {
    257                     if ( ! event.metaKey && ! event.ctrlKey ) {
    258                         if ( editor.dom.hasClass( event.target, 'edit' ) ) {
    259                             wp.mce.views.edit( view );
    260                         } else if ( editor.dom.hasClass( event.target, 'remove' ) ) {
    261                             editor.dom.remove( view );
    262                         }
     274                if ( event.type === 'click' && ! event.metaKey && ! event.ctrlKey ) {
     275                    if ( editor.dom.hasClass( event.target, 'edit' ) ) {
     276                        wp.mce.views.edit( view );
     277                    } else if ( editor.dom.hasClass( event.target, 'remove' ) ) {
     278                        editor.dom.remove( view );
    263279                    }
    264280                }
    265281                select( view );
    266                 // returning false stops the ugly bars from appearing in IE11 and stops the view being selected as a range in FF
    267                 // unfortunately, it also inhibits the dragging fo views to a new location
     282                // Returning false stops the ugly bars from appearing in IE11 and stops the view being selected as a range in FF.
     283                // Unfortunately, it also inhibits the dragging of views to a new location.
    268284                return false;
    269285            } else {
    270                 if ( event.type === 'click' ) {
     286                if ( event.type === 'mousedown' ) {
    271287                    deselect();
    272288                }
    273289            }
    274290        });
    275 
    276291    });
    277292
     
    297312            }
    298313
    299             // TODO: that makes all views into block tags (as we use <div>).
     314            // This makes all views into block tags (as we use <div>).
    300315            // Can use 'PostProcess' and a regex instead.
    301316            dom.replace( dom.create( 'p', null, window.decodeURIComponent( dom.getAttrib( node, 'data-wpview-text' ) ) ), node );
     
    331346        }
    332347
     348        // Deselect views with the arrow keys
    333349        if ( keyCode === VK.LEFT || keyCode === VK.UP ) {
    334350            deselect();
     
    337353                select( view.previousSibling );
    338354            // Handle case where view is the first node
    339             } else if ( view.previousSibling === null ) {
     355            } else if ( ! view.previousSibling ) {
    340356                padNode = createPadNode();
    341357                body.insertBefore( padNode, body.firstChild );
     
    352368                select( view.nextSibling );
    353369            // Handle case were the view is that last node
    354             } else if ( view.nextSibling === null ) {
     370            } else if ( ! view.nextSibling ) {
    355371                padNode = createPadNode();
    356372                body.appendChild( padNode );
     
    358374            // Handle default case where the next node is a non-wpview
    359375            } else {
    360                 editor.selection.setCursorLocation( view.nextSibling.firstChild, 0 );
     376                editor.selection.setCursorLocation( view.nextSibling, 0 );
    361377            }
    362378        } else if ( keyCode === VK.DELETE || keyCode === VK.BACKSPACE ) {
     
    368384    });
    369385
    370     // Select and deselect views when arrow keys are used to navigate the content of the editor.
     386    // Select views when arrow keys are used to navigate the content of the editor.
    371387    editor.on( 'keydown', function( event ) {
    372388        var keyCode = event.keyCode,
     389            dom = editor.dom,
    373390            range = editor.selection.getRng(),
     391            startNode = range.startContainer,
    374392            body = editor.getBody(),
    375             node;
    376 
    377         if ( ! range.collapsed || event.metaKey || event.ctrlKey ) {
    378             return;
    379         }
    380 
    381         if ( keyCode === VK.LEFT || keyCode === VK.UP ) {
    382             node = range.startContainer.parentNode === body ? range.startContainer : range.startContainer.parentNode;
    383             // The caret is directly after a wpview
    384             if ( range.startOffset === 0 && isView( node.previousSibling ) ) {
    385                 select( node.previousSibling );
     393            node, container;
     394
     395        if ( ! startNode || startNode === body || event.metaKey || event.ctrlKey ) {
     396            return;
     397        }
     398
     399        if ( keyCode === VK.UP || keyCode === VK.LEFT ) {
     400            if ( keyCode === VK.LEFT && ( ! range.collapsed || range.startOffset !== 0 ) ) {
     401                // Not at the beginning of the current range
     402                return;
     403            }
     404
     405            if ( ! ( node = dom.getParent( startNode, dom.isBlock ) ) ) {
     406                return;
     407            }
     408
     409            if ( selectSiblingView( node, 'previous' ) ) {
    386410                event.preventDefault();
    387411            }
    388         } else if ( keyCode === VK.RIGHT || keyCode === VK.DOWN ) {
    389             node = range.startContainer.parentNode === body ? range.startContainer : range.startContainer.parentNode;
    390             // The caret is directly before a wpview
    391             if ( ( ( range.startOffset === 0 && ! range.endContainer.length ) || ( range.startOffset === range.endContainer.length ) ) &&
    392                     isView( node.nextSibling ) ) {
    393                 select( node.nextSibling );
     412        } else if ( keyCode === VK.DOWN || keyCode === VK.RIGHT ) {
     413            if ( ! ( node = dom.getParent( startNode, dom.isBlock ) ) ) {
     414                return;
     415            }
     416
     417            if ( keyCode === VK.RIGHT ) {
     418                container = range.endContainer;
     419
     420                if ( ! range.collapsed || ( range.startOffset === 0 && container.length ) ||
     421                    container.nextSibling ||
     422                    ( container.nodeType === 3 && range.startOffset !== container.length ) ) { // Not at the end of the current range
     423
     424                    return;
     425                }
     426
     427                // In a child element
     428                while ( container && container !== node && container !== body ) {
     429                    if ( container.nextSibling ) {
     430                        return;
     431                    }
     432                    container = container.parentNode;
     433                }
     434            }
     435
     436            if ( selectSiblingView( node, 'next' ) ) {
    394437                event.preventDefault();
    395438            }
Note: See TracChangeset for help on using the changeset viewer.