wpView: select/deselect views when moving the caret with the arrow keys, don't move the caret after deselect(), props gcorne, see #26959
Built from https://develop.svn.wordpress.org/trunk@27632 git-svn-id: http://core.svn.wordpress.org/trunk@27475 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
bcb54794ff
commit
e05fa407bf
|
@ -109,15 +109,32 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
||||||
|
|
||||||
dom.unbind( selected, 'beforedeactivate focusin focusout click mouseup', _stop );
|
dom.unbind( selected, 'beforedeactivate focusin focusout click mouseup', _stop );
|
||||||
dom.removeClass( selected, 'selected' );
|
dom.removeClass( selected, 'selected' );
|
||||||
|
|
||||||
editor.selection.select( selected.nextSibling );
|
|
||||||
editor.selection.collapse();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selected = null;
|
selected = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectSiblingView( node, direction ) {
|
||||||
|
var body = editor.getBody(),
|
||||||
|
sibling = direction === 'previous' ? 'previousSibling' : 'nextSibling';
|
||||||
|
|
||||||
|
while ( node && node.parentNode !== body ) {
|
||||||
|
if ( node[sibling] ) {
|
||||||
|
// The caret will be in another element
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = node.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isView( node[sibling] ) ) {
|
||||||
|
select( node[sibling] );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the `wp.mce` API exists.
|
// Check if the `wp.mce` API exists.
|
||||||
if ( typeof wp === 'undefined' || ! wp.mce ) {
|
if ( typeof wp === 'undefined' || ! wp.mce ) {
|
||||||
return;
|
return;
|
||||||
|
@ -176,15 +193,16 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
||||||
x = event.clientX;
|
x = event.clientX;
|
||||||
y = event.clientY;
|
y = event.clientY;
|
||||||
|
|
||||||
|
// Detect clicks above or to the left if the first node is a wpview
|
||||||
if ( isView( firstNode ) && ( ( x < firstNode.offsetLeft && y < ( firstNode.offsetHeight - scrollTop ) ) ||
|
if ( isView( firstNode ) && ( ( x < firstNode.offsetLeft && y < ( firstNode.offsetHeight - scrollTop ) ) ||
|
||||||
y < firstNode.offsetTop ) ) {
|
y < firstNode.offsetTop ) ) {
|
||||||
// detect events above or to the left of the first view
|
|
||||||
|
|
||||||
padNode = createPadNode();
|
padNode = createPadNode();
|
||||||
body.insertBefore( padNode, firstNode );
|
body.insertBefore( padNode, firstNode );
|
||||||
|
|
||||||
|
// Detect clicks to the right and below the last view
|
||||||
} else if ( isView( lastNode ) && ( x > ( lastNode.offsetLeft + lastNode.offsetWidth ) ||
|
} else if ( isView( lastNode ) && ( x > ( lastNode.offsetLeft + lastNode.offsetWidth ) ||
|
||||||
( ( scrollTop + y ) - ( lastNode.offsetTop + lastNode.offsetHeight ) ) > 0 ) ) {
|
( ( scrollTop + y ) - ( lastNode.offsetTop + lastNode.offsetHeight ) ) > 0 ) ) {
|
||||||
// detect events to the right and below the last view
|
|
||||||
|
|
||||||
padNode = createPadNode();
|
padNode = createPadNode();
|
||||||
body.appendChild( padNode );
|
body.appendChild( padNode );
|
||||||
|
@ -253,26 +271,23 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
||||||
if ( view ) {
|
if ( view ) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
if ( event.type === 'click' ) {
|
if ( event.type === 'click' && ! event.metaKey && ! event.ctrlKey ) {
|
||||||
if ( ! event.metaKey && ! event.ctrlKey ) {
|
if ( editor.dom.hasClass( event.target, 'edit' ) ) {
|
||||||
if ( editor.dom.hasClass( event.target, 'edit' ) ) {
|
wp.mce.views.edit( view );
|
||||||
wp.mce.views.edit( view );
|
} else if ( editor.dom.hasClass( event.target, 'remove' ) ) {
|
||||||
} else if ( editor.dom.hasClass( event.target, 'remove' ) ) {
|
editor.dom.remove( view );
|
||||||
editor.dom.remove( view );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
select( view );
|
select( view );
|
||||||
// returning false stops the ugly bars from appearing in IE11 and stops the view being selected as a range in FF
|
// Returning false stops the ugly bars from appearing in IE11 and stops the view being selected as a range in FF.
|
||||||
// unfortunately, it also inhibits the dragging fo views to a new location
|
// Unfortunately, it also inhibits the dragging of views to a new location.
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if ( event.type === 'click' ) {
|
if ( event.type === 'mousedown' ) {
|
||||||
deselect();
|
deselect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.on( 'PreProcess', function( event ) {
|
editor.on( 'PreProcess', function( event ) {
|
||||||
|
@ -296,7 +311,7 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
||||||
node.innerText = '';
|
node.innerText = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: that makes all views into block tags (as we use <div>).
|
// This makes all views into block tags (as we use <div>).
|
||||||
// Can use 'PostProcess' and a regex instead.
|
// Can use 'PostProcess' and a regex instead.
|
||||||
dom.replace( dom.create( 'p', null, window.decodeURIComponent( dom.getAttrib( node, 'data-wpview-text' ) ) ), node );
|
dom.replace( dom.create( 'p', null, window.decodeURIComponent( dom.getAttrib( node, 'data-wpview-text' ) ) ), node );
|
||||||
});
|
});
|
||||||
|
@ -330,13 +345,14 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deselect views with the arrow keys
|
||||||
if ( keyCode === VK.LEFT || keyCode === VK.UP ) {
|
if ( keyCode === VK.LEFT || keyCode === VK.UP ) {
|
||||||
deselect();
|
deselect();
|
||||||
// Handle case where two views are stacked on top of one another
|
// Handle case where two views are stacked on top of one another
|
||||||
if ( isView( view.previousSibling ) ) {
|
if ( isView( view.previousSibling ) ) {
|
||||||
select( view.previousSibling );
|
select( view.previousSibling );
|
||||||
// Handle case where view is the first node
|
// Handle case where view is the first node
|
||||||
} else if ( view.previousSibling === null ) {
|
} else if ( ! view.previousSibling ) {
|
||||||
padNode = createPadNode();
|
padNode = createPadNode();
|
||||||
body.insertBefore( padNode, body.firstChild );
|
body.insertBefore( padNode, body.firstChild );
|
||||||
editor.selection.setCursorLocation( body.firstChild, 0 );
|
editor.selection.setCursorLocation( body.firstChild, 0 );
|
||||||
|
@ -351,13 +367,13 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
||||||
if ( isView( view.nextSibling ) ) {
|
if ( isView( view.nextSibling ) ) {
|
||||||
select( view.nextSibling );
|
select( view.nextSibling );
|
||||||
// Handle case were the view is that last node
|
// Handle case were the view is that last node
|
||||||
} else if ( view.nextSibling === null ) {
|
} else if ( ! view.nextSibling ) {
|
||||||
padNode = createPadNode();
|
padNode = createPadNode();
|
||||||
body.appendChild( padNode );
|
body.appendChild( padNode );
|
||||||
editor.selection.setCursorLocation( body.lastChild, 0 );
|
editor.selection.setCursorLocation( body.lastChild, 0 );
|
||||||
// Handle default case where the next node is a non-wpview
|
// Handle default case where the next node is a non-wpview
|
||||||
} else {
|
} else {
|
||||||
editor.selection.setCursorLocation( view.nextSibling.firstChild, 0 );
|
editor.selection.setCursorLocation( view.nextSibling, 0 );
|
||||||
}
|
}
|
||||||
} else if ( keyCode === VK.DELETE || keyCode === VK.BACKSPACE ) {
|
} else if ( keyCode === VK.DELETE || keyCode === VK.BACKSPACE ) {
|
||||||
// If delete or backspace is pressed, delete the view.
|
// If delete or backspace is pressed, delete the view.
|
||||||
|
@ -367,30 +383,57 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Select and deselect views when arrow keys are used to navigate the content of the editor.
|
// Select views when arrow keys are used to navigate the content of the editor.
|
||||||
editor.on( 'keydown', function( event ) {
|
editor.on( 'keydown', function( event ) {
|
||||||
var keyCode = event.keyCode,
|
var keyCode = event.keyCode,
|
||||||
|
dom = editor.dom,
|
||||||
range = editor.selection.getRng(),
|
range = editor.selection.getRng(),
|
||||||
|
startNode = range.startContainer,
|
||||||
body = editor.getBody(),
|
body = editor.getBody(),
|
||||||
node;
|
node, container;
|
||||||
|
|
||||||
if ( ! range.collapsed || event.metaKey || event.ctrlKey ) {
|
if ( ! startNode || startNode === body || event.metaKey || event.ctrlKey ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( keyCode === VK.LEFT || keyCode === VK.UP ) {
|
if ( keyCode === VK.UP || keyCode === VK.LEFT ) {
|
||||||
node = range.startContainer.parentNode === body ? range.startContainer : range.startContainer.parentNode;
|
if ( keyCode === VK.LEFT && ( ! range.collapsed || range.startOffset !== 0 ) ) {
|
||||||
// The caret is directly after a wpview
|
// Not at the beginning of the current range
|
||||||
if ( range.startOffset === 0 && isView( node.previousSibling ) ) {
|
return;
|
||||||
select( node.previousSibling );
|
}
|
||||||
|
|
||||||
|
if ( ! ( node = dom.getParent( startNode, dom.isBlock ) ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( selectSiblingView( node, 'previous' ) ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
} else if ( keyCode === VK.RIGHT || keyCode === VK.DOWN ) {
|
} else if ( keyCode === VK.DOWN || keyCode === VK.RIGHT ) {
|
||||||
node = range.startContainer.parentNode === body ? range.startContainer : range.startContainer.parentNode;
|
if ( ! ( node = dom.getParent( startNode, dom.isBlock ) ) ) {
|
||||||
// The caret is directly before a wpview
|
return;
|
||||||
if ( ( ( range.startOffset === 0 && ! range.endContainer.length ) || ( range.startOffset === range.endContainer.length ) ) &&
|
}
|
||||||
isView( node.nextSibling ) ) {
|
|
||||||
select( node.nextSibling );
|
if ( keyCode === VK.RIGHT ) {
|
||||||
|
container = range.endContainer;
|
||||||
|
|
||||||
|
if ( ! range.collapsed || ( range.startOffset === 0 && container.length ) ||
|
||||||
|
container.nextSibling ||
|
||||||
|
( container.nodeType === 3 && range.startOffset !== container.length ) ) { // Not at the end of the current range
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In a child element
|
||||||
|
while ( container && container !== node && container !== body ) {
|
||||||
|
if ( container.nextSibling ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
container = container.parentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( selectSiblingView( node, 'next' ) ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Loading…
Reference in New Issue