diff --git a/wp-includes/js/tinymce/plugins/wpview/plugin.js b/wp-includes/js/tinymce/plugins/wpview/plugin.js
index 932785949e..75f704788a 100644
--- a/wp-includes/js/tinymce/plugins/wpview/plugin.js
+++ b/wp-includes/js/tinymce/plugins/wpview/plugin.js
@@ -109,15 +109,32 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
dom.unbind( selected, 'beforedeactivate focusin focusout click mouseup', _stop );
dom.removeClass( selected, 'selected' );
-
- editor.selection.select( selected.nextSibling );
- editor.selection.collapse();
-
}
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.
if ( typeof wp === 'undefined' || ! wp.mce ) {
return;
@@ -176,15 +193,16 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
x = event.clientX;
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 ) ) ||
y < firstNode.offsetTop ) ) {
- // detect events above or to the left of the first view
padNode = createPadNode();
body.insertBefore( padNode, firstNode );
+
+ // Detect clicks to the right and below the last view
} else if ( isView( lastNode ) && ( x > ( lastNode.offsetLeft + lastNode.offsetWidth ) ||
( ( scrollTop + y ) - ( lastNode.offsetTop + lastNode.offsetHeight ) ) > 0 ) ) {
- // detect events to the right and below the last view
padNode = createPadNode();
body.appendChild( padNode );
@@ -253,26 +271,23 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
if ( view ) {
event.stopPropagation();
- if ( event.type === 'click' ) {
- if ( ! event.metaKey && ! event.ctrlKey ) {
- if ( editor.dom.hasClass( event.target, 'edit' ) ) {
- wp.mce.views.edit( view );
- } else if ( editor.dom.hasClass( event.target, 'remove' ) ) {
- editor.dom.remove( view );
- }
+ if ( event.type === 'click' && ! event.metaKey && ! event.ctrlKey ) {
+ if ( editor.dom.hasClass( event.target, 'edit' ) ) {
+ wp.mce.views.edit( view );
+ } else if ( editor.dom.hasClass( event.target, 'remove' ) ) {
+ editor.dom.remove( view );
}
}
select( view );
- // 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
+ // 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 of views to a new location.
return false;
} else {
- if ( event.type === 'click' ) {
+ if ( event.type === 'mousedown' ) {
deselect();
}
}
});
-
});
editor.on( 'PreProcess', function( event ) {
@@ -296,7 +311,7 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
node.innerText = '';
}
- // TODO: that makes all views into block tags (as we use
).
+ // This makes all views into block tags (as we use
).
// Can use 'PostProcess' and a regex instead.
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;
}
+ // Deselect views with the arrow keys
if ( keyCode === VK.LEFT || keyCode === VK.UP ) {
deselect();
// Handle case where two views are stacked on top of one another
if ( isView( view.previousSibling ) ) {
select( view.previousSibling );
// Handle case where view is the first node
- } else if ( view.previousSibling === null ) {
+ } else if ( ! view.previousSibling ) {
padNode = createPadNode();
body.insertBefore( padNode, body.firstChild );
editor.selection.setCursorLocation( body.firstChild, 0 );
@@ -351,13 +367,13 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
if ( isView( view.nextSibling ) ) {
select( view.nextSibling );
// Handle case were the view is that last node
- } else if ( view.nextSibling === null ) {
+ } else if ( ! view.nextSibling ) {
padNode = createPadNode();
body.appendChild( padNode );
editor.selection.setCursorLocation( body.lastChild, 0 );
// Handle default case where the next node is a non-wpview
} else {
- editor.selection.setCursorLocation( view.nextSibling.firstChild, 0 );
+ editor.selection.setCursorLocation( view.nextSibling, 0 );
}
} else if ( keyCode === VK.DELETE || keyCode === VK.BACKSPACE ) {
// If delete or backspace is pressed, delete the view.
@@ -367,30 +383,57 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
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 ) {
var keyCode = event.keyCode,
+ dom = editor.dom,
range = editor.selection.getRng(),
+ startNode = range.startContainer,
body = editor.getBody(),
- node;
+ node, container;
- if ( ! range.collapsed || event.metaKey || event.ctrlKey ) {
+ if ( ! startNode || startNode === body || event.metaKey || event.ctrlKey ) {
return;
}
- if ( keyCode === VK.LEFT || keyCode === VK.UP ) {
- node = range.startContainer.parentNode === body ? range.startContainer : range.startContainer.parentNode;
- // The caret is directly after a wpview
- if ( range.startOffset === 0 && isView( node.previousSibling ) ) {
- select( node.previousSibling );
+ if ( keyCode === VK.UP || keyCode === VK.LEFT ) {
+ if ( keyCode === VK.LEFT && ( ! range.collapsed || range.startOffset !== 0 ) ) {
+ // Not at the beginning of the current range
+ return;
+ }
+
+ if ( ! ( node = dom.getParent( startNode, dom.isBlock ) ) ) {
+ return;
+ }
+
+ if ( selectSiblingView( node, 'previous' ) ) {
event.preventDefault();
}
- } else if ( keyCode === VK.RIGHT || keyCode === VK.DOWN ) {
- node = range.startContainer.parentNode === body ? range.startContainer : range.startContainer.parentNode;
- // The caret is directly before a wpview
- if ( ( ( range.startOffset === 0 && ! range.endContainer.length ) || ( range.startOffset === range.endContainer.length ) ) &&
- isView( node.nextSibling ) ) {
- select( node.nextSibling );
+ } else if ( keyCode === VK.DOWN || keyCode === VK.RIGHT ) {
+ if ( ! ( node = dom.getParent( startNode, dom.isBlock ) ) ) {
+ return;
+ }
+
+ 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();
}
}
diff --git a/wp-includes/js/tinymce/plugins/wpview/plugin.min.js b/wp-includes/js/tinymce/plugins/wpview/plugin.min.js
index 6b05d567f5..9117193164 100644
--- a/wp-includes/js/tinymce/plugins/wpview/plugin.min.js
+++ b/wp-includes/js/tinymce/plugins/wpview/plugin.min.js
@@ -1 +1 @@
-tinymce.PluginManager.add("wpview",function(a){function b(a){for(;a&&"BODY"!==a.nodeName;){if(c(a))return a;a=a.parentNode}}function c(a){return a&&/\bwpview-wrap\b/.test(a.className)}function d(){return a.dom.create("p",{"data-wpview-pad":1},tinymce.Env.ie&&tinymce.Env.ie<11?"":'
')}function e(c){return c=b("string"==typeof c?a.dom.get(c):c),c?window.decodeURIComponent(a.dom.getAttrib(c,"data-wpview-text")||""):""}function f(c,d){return c=b("string"==typeof c?a.dom.get(c):c),c?(a.dom.setAttrib(c,"data-wpview-text",window.encodeURIComponent(d||"")),!0):!1}function g(a){a.stopPropagation()}function h(b){var c,d=a.dom;b!==j&&(i(),j=b,d.addClass(b,"selected"),c=d.create("div",{"class":"wpview-clipboard",contenteditable:"true"},e(b)),b.appendChild(c),a.dom.bind(c,"beforedeactivate focusin focusout",g),a.dom.bind(j,"beforedeactivate focusin focusout",g),a.getBody().focus(),a.selection.select(c,!0))}function i(){var b,c=a.dom;j&&(b=a.dom.select(".wpview-clipboard",j)[0],c.unbind(b),c.remove(b),c.unbind(j,"beforedeactivate focusin focusout click mouseup",g),c.removeClass(j,"selected"),a.selection.select(j.nextSibling),a.selection.collapse()),j=null}var j,k=tinymce.util.VK,l=tinymce.dom.TreeWalker,m=!1;if("undefined"!=typeof wp&&wp.mce)return a.on("BeforeAddUndo",function(a){j&&!m&&a.preventDefault()}),a.on("BeforeSetContent",function(a){a.content&&(a.content=wp.mce.views.toViews(a.content))}),a.on("SetContent",function(b){var e,f;"raw"!==b.format&&wp.mce.views.render(),(b.load||!b.set)&&(e=a.getBody(),c(e.lastChild)&&(f=d(),e.appendChild(f),a.selection.setCursorLocation(f,0)))}),a.on("click",function(b){var e,f,g,h,j,k=a.getBody(),l=a.getDoc(),m=l.documentElement.scrollTop||k.scrollTop||0;"HTML"!==b.target.nodeName||b.metaKey||b.ctrlKey||(g=k.firstChild,h=k.lastChild,e=b.clientX,f=b.clientY,c(g)&&(eh.offsetLeft+h.offsetWidth||m+f-(h.offsetTop+h.offsetHeight)>0)&&(j=d(),k.appendChild(j)),j&&(i(),a.getBody().focus(),a.selection.setCursorLocation(j,0)))}),a.on("init",function(){var d=a.selection;a.on("BeforeSetContent",function(){var e,f,g=b(d.getNode());g&&(!g.nextSibling||c(g.nextSibling)?(f=a.getDoc().createTextNode(""),a.dom.insertAfter(f,g)):(e=new l(g.nextSibling,g.nextSibling),f=e.next()),d.select(f),d.collapse(!0))}),a.on("SetContent",function(a){if(a.context){var b=d.getNode();b.innerHTML&&(b.innerHTML=wp.mce.views.toViews(b.innerHTML))}}),a.dom.bind(a.getBody(),"mousedown mouseup click",function(c){var d=b(c.target);return d?(c.stopPropagation(),"click"===c.type&&(c.metaKey||c.ctrlKey||(a.dom.hasClass(c.target,"edit")?wp.mce.views.edit(d):a.dom.hasClass(c.target,"remove")&&a.dom.remove(d))),h(d),!1):void("click"===c.type&&i())})}),a.on("PreProcess",function(b){var c=a.dom;tinymce.each(c.select("p[data-wpview-pad]",b.node),function(a){c.isEmpty(a)?c.remove(a):c.setAttrib(a,"data-wpview-pad",null)}),tinymce.each(c.select("div[data-wpview-text]",b.node),function(a){"textContent"in a?a.textContent="":a.innerText="",c.replace(c.create("p",null,window.decodeURIComponent(c.getAttrib(a,"data-wpview-text"))),a)})}),a.on("keydown",function(e){var f,g,l=e.keyCode,n=a.getBody();if(j){if(e.metaKey||e.ctrlKey||l>=112&&123>=l)return void((e.metaKey||e.ctrlKey)&&88===l&&(m=j));if(f=b(a.selection.getNode()),f!==j)return void i();l===k.LEFT||l===k.UP?(i(),c(f.previousSibling)?h(f.previousSibling):null===f.previousSibling?(g=d(),n.insertBefore(g,n.firstChild),a.selection.setCursorLocation(n.firstChild,0)):(a.selection.select(f.previousSibling,!0),a.selection.collapse())):l===k.RIGHT||l===k.DOWN?(i(),c(f.nextSibling)?h(f.nextSibling):null===f.nextSibling?(g=d(),n.appendChild(g),a.selection.setCursorLocation(n.lastChild,0)):a.selection.setCursorLocation(f.nextSibling.firstChild,0)):(l===k.DELETE||l===k.BACKSPACE)&&a.dom.remove(j),e.preventDefault()}}),a.on("keydown",function(b){var d,e=b.keyCode,f=a.selection.getRng(),g=a.getBody();!f.collapsed||b.metaKey||b.ctrlKey||(e===k.LEFT||e===k.UP?(d=f.startContainer.parentNode===g?f.startContainer:f.startContainer.parentNode,0===f.startOffset&&c(d.previousSibling)&&(h(d.previousSibling),b.preventDefault())):(e===k.RIGHT||e===k.DOWN)&&(d=f.startContainer.parentNode===g?f.startContainer:f.startContainer.parentNode,(0===f.startOffset&&!f.endContainer.length||f.startOffset===f.endContainer.length)&&c(d.nextSibling)&&(h(d.nextSibling),b.preventDefault())))}),a.on("keyup",function(b){var e,f,g=b.keyCode,h=a.getBody();m&&(a.dom.remove(m),m=!1),(g===k.DELETE||g===k.BACKSPACE)&&(c(h.lastChild)&&(e=d(),h.appendChild(e),2===h.childNodes.length&&a.selection.setCursorLocation(e,0)),f=a.selection.getRng(),h.firstChild===f.startContainer&&f.collapsed===!0&&c(f.startContainer.nextSibling)&&0===f.startOffset&&a.dom.remove(f.startContainer))}),{getViewText:e,setViewText:f}});
\ No newline at end of file
+tinymce.PluginManager.add("wpview",function(a){function b(a){for(;a&&"BODY"!==a.nodeName;){if(c(a))return a;a=a.parentNode}}function c(a){return a&&/\bwpview-wrap\b/.test(a.className)}function d(){return a.dom.create("p",{"data-wpview-pad":1},tinymce.Env.ie&&tinymce.Env.ie<11?"":'
')}function e(c){return c=b("string"==typeof c?a.dom.get(c):c),c?window.decodeURIComponent(a.dom.getAttrib(c,"data-wpview-text")||""):""}function f(c,d){return c=b("string"==typeof c?a.dom.get(c):c),c?(a.dom.setAttrib(c,"data-wpview-text",window.encodeURIComponent(d||"")),!0):!1}function g(a){a.stopPropagation()}function h(b){var c,d=a.dom;b!==k&&(i(),k=b,d.addClass(b,"selected"),c=d.create("div",{"class":"wpview-clipboard",contenteditable:"true"},e(b)),b.appendChild(c),a.dom.bind(c,"beforedeactivate focusin focusout",g),a.dom.bind(k,"beforedeactivate focusin focusout",g),a.getBody().focus(),a.selection.select(c,!0))}function i(){var b,c=a.dom;k&&(b=a.dom.select(".wpview-clipboard",k)[0],c.unbind(b),c.remove(b),c.unbind(k,"beforedeactivate focusin focusout click mouseup",g),c.removeClass(k,"selected")),k=null}function j(b,d){for(var e=a.getBody(),f="previous"===d?"previousSibling":"nextSibling";b&&b.parentNode!==e;){if(b[f])return!1;b=b.parentNode}return c(b[f])?(h(b[f]),!0):!1}var k,l=tinymce.util.VK,m=tinymce.dom.TreeWalker,n=!1;if("undefined"!=typeof wp&&wp.mce)return a.on("BeforeAddUndo",function(a){k&&!n&&a.preventDefault()}),a.on("BeforeSetContent",function(a){a.content&&(a.content=wp.mce.views.toViews(a.content))}),a.on("SetContent",function(b){var e,f;"raw"!==b.format&&wp.mce.views.render(),(b.load||!b.set)&&(e=a.getBody(),c(e.lastChild)&&(f=d(),e.appendChild(f),a.selection.setCursorLocation(f,0)))}),a.on("click",function(b){var e,f,g,h,j,k=a.getBody(),l=a.getDoc(),m=l.documentElement.scrollTop||k.scrollTop||0;"HTML"!==b.target.nodeName||b.metaKey||b.ctrlKey||(g=k.firstChild,h=k.lastChild,e=b.clientX,f=b.clientY,c(g)&&(eh.offsetLeft+h.offsetWidth||m+f-(h.offsetTop+h.offsetHeight)>0)&&(j=d(),k.appendChild(j)),j&&(i(),a.getBody().focus(),a.selection.setCursorLocation(j,0)))}),a.on("init",function(){var d=a.selection;a.on("BeforeSetContent",function(){var e,f,g=b(d.getNode());g&&(!g.nextSibling||c(g.nextSibling)?(f=a.getDoc().createTextNode(""),a.dom.insertAfter(f,g)):(e=new m(g.nextSibling,g.nextSibling),f=e.next()),d.select(f),d.collapse(!0))}),a.on("SetContent",function(a){if(a.context){var b=d.getNode();b.innerHTML&&(b.innerHTML=wp.mce.views.toViews(b.innerHTML))}}),a.dom.bind(a.getBody(),"mousedown mouseup click",function(c){var d=b(c.target);return d?(c.stopPropagation(),"click"!==c.type||c.metaKey||c.ctrlKey||(a.dom.hasClass(c.target,"edit")?wp.mce.views.edit(d):a.dom.hasClass(c.target,"remove")&&a.dom.remove(d)),h(d),!1):void("mousedown"===c.type&&i())})}),a.on("PreProcess",function(b){var c=a.dom;tinymce.each(c.select("p[data-wpview-pad]",b.node),function(a){c.isEmpty(a)?c.remove(a):c.setAttrib(a,"data-wpview-pad",null)}),tinymce.each(c.select("div[data-wpview-text]",b.node),function(a){"textContent"in a?a.textContent="":a.innerText="",c.replace(c.create("p",null,window.decodeURIComponent(c.getAttrib(a,"data-wpview-text"))),a)})}),a.on("keydown",function(e){var f,g,j=e.keyCode,m=a.getBody();if(k){if(e.metaKey||e.ctrlKey||j>=112&&123>=j)return void((e.metaKey||e.ctrlKey)&&88===j&&(n=k));if(f=b(a.selection.getNode()),f!==k)return void i();j===l.LEFT||j===l.UP?(i(),c(f.previousSibling)?h(f.previousSibling):f.previousSibling?(a.selection.select(f.previousSibling,!0),a.selection.collapse()):(g=d(),m.insertBefore(g,m.firstChild),a.selection.setCursorLocation(m.firstChild,0))):j===l.RIGHT||j===l.DOWN?(i(),c(f.nextSibling)?h(f.nextSibling):f.nextSibling?a.selection.setCursorLocation(f.nextSibling,0):(g=d(),m.appendChild(g),a.selection.setCursorLocation(m.lastChild,0))):(j===l.DELETE||j===l.BACKSPACE)&&a.dom.remove(k),e.preventDefault()}}),a.on("keydown",function(b){var c,d,e=b.keyCode,f=a.dom,g=a.selection.getRng(),h=g.startContainer,i=a.getBody();if(h&&h!==i&&!b.metaKey&&!b.ctrlKey)if(e===l.UP||e===l.LEFT){if(e===l.LEFT&&(!g.collapsed||0!==g.startOffset))return;if(!(c=f.getParent(h,f.isBlock)))return;j(c,"previous")&&b.preventDefault()}else if(e===l.DOWN||e===l.RIGHT){if(!(c=f.getParent(h,f.isBlock)))return;if(e===l.RIGHT){if(d=g.endContainer,!g.collapsed||0===g.startOffset&&d.length||d.nextSibling||3===d.nodeType&&g.startOffset!==d.length)return;for(;d&&d!==c&&d!==i;){if(d.nextSibling)return;d=d.parentNode}}j(c,"next")&&b.preventDefault()}}),a.on("keyup",function(b){var e,f,g=b.keyCode,h=a.getBody();n&&(a.dom.remove(n),n=!1),(g===l.DELETE||g===l.BACKSPACE)&&(c(h.lastChild)&&(e=d(),h.appendChild(e),2===h.childNodes.length&&a.selection.setCursorLocation(e,0)),f=a.selection.getRng(),h.firstChild===f.startContainer&&f.collapsed===!0&&c(f.startContainer.nextSibling)&&0===f.startOffset&&a.dom.remove(f.startContainer))}),{getViewText:e,setViewText:f}});
\ No newline at end of file
diff --git a/wp-includes/js/tinymce/wp-tinymce.js.gz b/wp-includes/js/tinymce/wp-tinymce.js.gz
index c103883ce1..705004d08a 100644
Binary files a/wp-includes/js/tinymce/wp-tinymce.js.gz and b/wp-includes/js/tinymce/wp-tinymce.js.gz differ