diff -r 490d5cc509ed -r cf61fcea0001 wp/wp-includes/js/wplink.js
--- a/wp/wp-includes/js/wplink.js Tue Jun 09 11:14:17 2015 +0000
+++ b/wp/wp-includes/js/wplink.js Mon Oct 14 17:39:30 2019 +0200
@@ -1,14 +1,15 @@
-/* global ajaxurl, tinymce, wpLinkL10n, setUserSetting, wpActiveEditor */
var wpLink;
-( function( $ ) {
- var editor, searchTimer, River, Query, correctedURL,
+( function( $, wpLinkL10n, wp ) {
+ var editor, searchTimer, River, Query, correctedURL, linkNode,
+ emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,63}$/i,
+ urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,63}[^ "]*$/i,
inputs = {},
rivers = {},
isTouch = ( 'ontouchend' in document );
function getLink() {
- return editor.dom.getParent( editor.selection.getNode(), 'a' );
+ return linkNode || editor.dom.getParent( editor.selection.getNode(), 'a[href]' );
}
wpLink = {
@@ -18,6 +19,7 @@
keySensitivity: 100,
lastSearch: '',
textarea: '',
+ modalOpen: false,
init: function() {
inputs.wrap = $('#wp-link-wrap');
@@ -50,13 +52,12 @@
event.preventDefault();
wpLink.update();
});
- inputs.close.add( inputs.backdrop ).add( '#wp-link-cancel a' ).click( function( event ) {
+
+ inputs.close.add( inputs.backdrop ).add( '#wp-link-cancel button' ).click( function( event ) {
event.preventDefault();
wpLink.close();
});
- $( '#wp-link-search-toggle' ).on( 'click', wpLink.toggleInternalLinking );
-
rivers.elements.on( 'river-select', wpLink.updateFields );
// Display 'hint' message when search field or 'query-results' box are focused
@@ -68,35 +69,37 @@
inputs.queryNoticeTextHint.addClass( 'screen-reader-text' ).hide();
} );
- inputs.search.keyup( function() {
- var self = this;
-
+ inputs.search.on( 'keyup input', function() {
window.clearTimeout( searchTimer );
searchTimer = window.setTimeout( function() {
- wpLink.searchInternalLinks.call( self );
+ wpLink.searchInternalLinks();
}, 500 );
});
- function correctURL() {
- var url = $.trim( inputs.url.val() );
-
- if ( url && correctedURL !== url && ! /^(?:[a-z]+:|#|\?|\.|\/)/.test( url ) ) {
- inputs.url.val( 'http://' + url );
- correctedURL = url;
- }
- }
-
inputs.url.on( 'paste', function() {
- setTimeout( correctURL, 0 );
+ setTimeout( wpLink.correctURL, 0 );
} );
- inputs.url.on( 'blur', correctURL );
+ inputs.url.on( 'blur', wpLink.correctURL );
},
- open: function( editorId ) {
- var ed;
+ // If URL wasn't corrected last time and doesn't start with http:, https:, ? # or /, prepend http://
+ correctURL: function () {
+ var url = $.trim( inputs.url.val() );
- $( document.body ).addClass( 'modal-open' );
+ if ( url && correctedURL !== url && ! /^(?:[a-z]+:|#|\?|\.|\/)/.test( url ) ) {
+ inputs.url.val( 'http://' + url );
+ correctedURL = url;
+ }
+ },
+
+ open: function( editorId, url, text, node ) {
+ var ed,
+ $body = $( document.body );
+
+ $body.addClass( 'modal-open' );
+ wpLink.modalOpen = true;
+ linkNode = node;
wpLink.range = null;
@@ -110,18 +113,18 @@
this.textarea = $( '#' + window.wpActiveEditor ).get( 0 );
- if ( typeof tinymce !== 'undefined' ) {
- ed = tinymce.get( wpActiveEditor );
+ if ( typeof window.tinymce !== 'undefined' ) {
+ // Make sure the link wrapper is the last element in the body,
+ // or the inline editor toolbar may show above the backdrop.
+ $body.append( inputs.backdrop, inputs.wrap );
+
+ ed = window.tinymce.get( window.wpActiveEditor );
if ( ed && ! ed.isHidden() ) {
editor = ed;
} else {
editor = null;
}
-
- if ( editor && tinymce.isIE ) {
- editor.windowManager.bookmark = editor.selection.getBookmark();
- }
}
if ( ! wpLink.isMCE() && document.selection ) {
@@ -132,7 +135,7 @@
inputs.wrap.show();
inputs.backdrop.show();
- wpLink.refresh();
+ wpLink.refresh( url, text );
$( document ).trigger( 'wplink-open', inputs.wrap );
},
@@ -141,15 +144,15 @@
return editor && ! editor.isHidden();
},
- refresh: function() {
- var text = '';
+ refresh: function( url, text ) {
+ var linkText = '';
// Refresh rivers (clear links, check visibility)
rivers.search.refresh();
rivers.recent.refresh();
if ( wpLink.isMCE() ) {
- wpLink.mceRefresh();
+ wpLink.mceRefresh( url, text );
} else {
// For the Text editor the "Link text" field is always shown
if ( ! inputs.wrap.hasClass( 'has-text-field' ) ) {
@@ -158,11 +161,11 @@
if ( document.selection ) {
// Old IE
- text = document.selection.createRange().text || '';
+ linkText = document.selection.createRange().text || text || '';
} else if ( typeof this.textarea.selectionStart !== 'undefined' &&
( this.textarea.selectionStart !== this.textarea.selectionEnd ) ) {
// W3C
- text = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd ) || '';
+ text = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd ) || text || '';
}
inputs.text.val( text );
@@ -176,7 +179,10 @@
// Focus the URL field and highlight its contents.
// If this is moved above the selection changes,
// IE will show a flashing cursor over the dialog.
- inputs.url.focus()[0].select();
+ window.setTimeout( function() {
+ inputs.url[0].select();
+ inputs.url.focus();
+ } );
}
// Load the most recent results if this is the first time opening the panel.
@@ -188,7 +194,7 @@
},
hasSelectedText: function( linkNode ) {
- var html = editor.selection.getContent();
+ var node, nodes, i, html = editor.selection.getContent();
// Partial html and not a fully selected anchor element
if ( /]+>[^<]+<\/a>$/.test( html ) || html.indexOf('href=') === -1 ) ) {
@@ -196,14 +202,16 @@
}
if ( linkNode ) {
- var nodes = linkNode.childNodes, i;
+ nodes = linkNode.childNodes;
if ( nodes.length === 0 ) {
return false;
}
for ( i = nodes.length - 1; i >= 0; i-- ) {
- if ( nodes[i].nodeType != 3 ) {
+ node = nodes[i];
+
+ if ( node.nodeType != 3 && ! window.tinymce.dom.BookmarkManager.isBookmarkNode( node ) ) {
return false;
}
}
@@ -212,24 +220,49 @@
return true;
},
- mceRefresh: function() {
- var text,
- selectedNode = editor.selection.getNode(),
- linkNode = editor.dom.getParent( selectedNode, 'a[href]' ),
+ mceRefresh: function( searchStr, text ) {
+ var linkText, href,
+ linkNode = getLink(),
onlyText = this.hasSelectedText( linkNode );
if ( linkNode ) {
- text = linkNode.innerText || linkNode.textContent;
- inputs.url.val( editor.dom.getAttrib( linkNode, 'href' ) );
- inputs.openInNewTab.prop( 'checked', '_blank' === editor.dom.getAttrib( linkNode, 'target' ) );
- inputs.submit.val( wpLinkL10n.update );
+ linkText = linkNode.textContent || linkNode.innerText;
+ href = editor.dom.getAttrib( linkNode, 'href' );
+
+ if ( ! $.trim( linkText ) ) {
+ linkText = text || '';
+ }
+
+ if ( searchStr && ( urlRegexp.test( searchStr ) || emailRegexp.test( searchStr ) ) ) {
+ href = searchStr;
+ }
+
+ if ( href !== '_wp_link_placeholder' ) {
+ inputs.url.val( href );
+ inputs.openInNewTab.prop( 'checked', '_blank' === editor.dom.getAttrib( linkNode, 'target' ) );
+ inputs.submit.val( wpLinkL10n.update );
+ } else {
+ this.setDefaultValues( linkText );
+ }
+
+ if ( searchStr && searchStr !== href ) {
+ // The user has typed something in the inline dialog. Trigger a search with it.
+ inputs.search.val( searchStr );
+ } else {
+ inputs.search.val( '' );
+ }
+
+ // Always reset the search
+ window.setTimeout( function() {
+ wpLink.searchInternalLinks();
+ } );
} else {
- text = editor.selection.getContent({ format: 'text' });
- this.setDefaultValues();
+ linkText = editor.selection.getContent({ format: 'text' }) || text || '';
+ this.setDefaultValues( linkText );
}
if ( onlyText ) {
- inputs.text.val( text || '' );
+ inputs.text.val( linkText );
inputs.wrap.addClass( 'has-text-field' );
} else {
inputs.text.val( '' );
@@ -237,18 +270,25 @@
}
},
- close: function() {
+ close: function( reset ) {
$( document.body ).removeClass( 'modal-open' );
+ wpLink.modalOpen = false;
- if ( ! wpLink.isMCE() ) {
- wpLink.textarea.focus();
+ if ( reset !== 'noReset' ) {
+ if ( ! wpLink.isMCE() ) {
+ wpLink.textarea.focus();
- if ( wpLink.range ) {
- wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
- wpLink.range.select();
+ if ( wpLink.range ) {
+ wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
+ wpLink.range.select();
+ }
+ } else {
+ if ( editor.plugins.wplink ) {
+ editor.plugins.wplink.close();
+ }
+
+ editor.focus();
}
- } else {
- editor.focus();
}
inputs.backdrop.hide();
@@ -260,12 +300,24 @@
},
getAttrs: function() {
+ wpLink.correctURL();
+
return {
href: $.trim( inputs.url.val() ),
- target: inputs.openInNewTab.prop( 'checked' ) ? '_blank' : ''
+ target: inputs.openInNewTab.prop( 'checked' ) ? '_blank' : null
};
},
+ buildHtml: function(attrs) {
+ var html = '';
+ },
+
update: function() {
if ( wpLink.isMCE() ) {
wpLink.mceUpdate();
@@ -285,19 +337,19 @@
attrs = wpLink.getAttrs();
text = inputs.text.val();
+ var parser = document.createElement( 'a' );
+ parser.href = attrs.href;
+
+ if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
+ attrs.href = '';
+ }
+
// If there's no href, return.
if ( ! attrs.href ) {
return;
}
- // Build HTML
- html = '';
+ html = wpLink.buildHtml(attrs);
// Insert HTML
if ( document.selection && wpLink.range ) {
@@ -335,81 +387,123 @@
wpLink.close();
textarea.focus();
+ $( textarea ).trigger( 'change' );
+
+ // Audible confirmation message when a link has been inserted in the Editor.
+ wp.a11y.speak( wpLinkL10n.linkInserted );
},
mceUpdate: function() {
var attrs = wpLink.getAttrs(),
- link, text;
+ $link, text, hasText, $mceCaret;
- wpLink.close();
- editor.focus();
+ var parser = document.createElement( 'a' );
+ parser.href = attrs.href;
- if ( tinymce.isIE ) {
- editor.selection.moveToBookmark( editor.windowManager.bookmark );
+ if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
+ attrs.href = '';
}
if ( ! attrs.href ) {
editor.execCommand( 'unlink' );
+ wpLink.close();
return;
}
- link = getLink();
- text = inputs.text.val();
+ $link = editor.$( getLink() );
- if ( link ) {
- if ( text ) {
- if ( 'innerText' in link ) {
- link.innerText = text;
- } else {
- link.textContent = text;
- }
+ editor.undoManager.transact( function() {
+ if ( ! $link.length ) {
+ editor.execCommand( 'mceInsertLink', false, { href: '_wp_link_placeholder', 'data-wp-temp-link': 1 } );
+ $link = editor.$( 'a[data-wp-temp-link="1"]' ).removeAttr( 'data-wp-temp-link' );
+ hasText = $.trim( $link.text() );
}
- editor.dom.setAttribs( link, attrs );
- } else {
- if ( text ) {
- editor.selection.setNode( editor.dom.create( 'a', attrs, text ) );
+ if ( ! $link.length ) {
+ editor.execCommand( 'unlink' );
} else {
- editor.execCommand( 'mceInsertLink', false, attrs );
+ if ( inputs.wrap.hasClass( 'has-text-field' ) ) {
+ text = inputs.text.val();
+
+ if ( text ) {
+ $link.text( text );
+ } else if ( ! hasText ) {
+ $link.text( attrs.href );
+ }
+ }
+
+ attrs['data-wplink-edit'] = null;
+ attrs['data-mce-href'] = null; // attrs.href
+ $link.attr( attrs );
+ }
+ } );
+
+ wpLink.close( 'noReset' );
+ editor.focus();
+
+ if ( $link.length ) {
+ $mceCaret = $link.parent( '#_mce_caret' );
+
+ if ( $mceCaret.length ) {
+ $mceCaret.before( $link.removeAttr( 'data-mce-bogus' ) );
+ }
+
+ editor.selection.select( $link[0] );
+ editor.selection.collapse();
+
+ if ( editor.plugins.wplink ) {
+ editor.plugins.wplink.checkLink( $link[0] );
}
}
+
+ editor.nodeChanged();
+
+ // Audible confirmation message when a link has been inserted in the Editor.
+ wp.a11y.speak( wpLinkL10n.linkInserted );
},
updateFields: function( e, li ) {
inputs.url.val( li.children( '.item-permalink' ).val() );
},
- setDefaultValues: function() {
- var selection,
- emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
- urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i;
+ getUrlFromSelection: function( selection ) {
+ if ( ! selection ) {
+ if ( this.isMCE() ) {
+ selection = editor.selection.getContent({ format: 'text' });
+ } else if ( document.selection && wpLink.range ) {
+ selection = wpLink.range.text;
+ } else if ( typeof this.textarea.selectionStart !== 'undefined' ) {
+ selection = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd );
+ }
+ }
- if ( this.isMCE() ) {
- selection = editor.selection.getContent();
- } else if ( document.selection && wpLink.range ) {
- selection = wpLink.range.text;
- } else if ( typeof this.textarea.selectionStart !== 'undefined' ) {
- selection = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd );
- }
+ selection = $.trim( selection );
if ( selection && emailRegexp.test( selection ) ) {
// Selection is email address
- inputs.url.val( 'mailto:' + selection );
+ return 'mailto:' + selection;
} else if ( selection && urlRegexp.test( selection ) ) {
// Selection is URL
- inputs.url.val( selection.replace( /&|?38;/gi, '&' ) );
- } else {
- // Set URL to default.
- inputs.url.val( '' );
+ return selection.replace( /&|?38;/gi, '&' );
}
+ return '';
+ },
+
+ setDefaultValues: function( selection ) {
+ inputs.url.val( this.getUrlFromSelection( selection ) );
+
+ // Empty the search field and swap the "rivers".
+ inputs.search.val('');
+ wpLink.searchInternalLinks();
+
// Update save prompt.
inputs.submit.val( wpLinkL10n.save );
},
searchInternalLinks: function() {
- var t = $( this ), waiting,
- search = t.val();
+ var waiting,
+ search = inputs.search.val() || '';
if ( search.length > 2 ) {
rivers.recent.hide();
@@ -420,7 +514,7 @@
return;
wpLink.lastSearch = search;
- waiting = t.parent().find( '.spinner' ).addClass( 'is-active' );
+ waiting = inputs.search.parent().find( '.spinner' ).addClass( 'is-active' );
rivers.search.change( search );
rivers.search.ajax( function() {
@@ -443,13 +537,14 @@
},
keydown: function( event ) {
- var fn, id,
- key = $.ui.keyCode;
+ var fn, id;
- if ( key.ESCAPE === event.keyCode ) {
+ // Escape key.
+ if ( 27 === event.keyCode ) {
wpLink.close();
event.stopImmediatePropagation();
- } else if ( key.TAB === event.keyCode ) {
+ // Tab key.
+ } else if ( 9 === event.keyCode ) {
id = event.target.id;
// wp-link-submit must always be the last focusable element in the dialog.
@@ -463,7 +558,8 @@
}
}
- if ( event.keyCode !== key.UP && event.keyCode !== key.DOWN ) {
+ // Up Arrow and Down Arrow keys.
+ if ( 38 !== event.keyCode && 40 !== event.keyCode ) {
return;
}
@@ -472,7 +568,8 @@
return;
}
- fn = event.keyCode === key.UP ? 'prev' : 'next';
+ // Up Arrow key.
+ fn = 38 === event.keyCode ? 'prev' : 'next';
clearInterval( wpLink.keyInterval );
wpLink[ fn ]();
wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity );
@@ -480,9 +577,8 @@
},
keyup: function( event ) {
- var key = $.ui.keyCode;
-
- if ( event.which === key.UP || event.which === key.DOWN ) {
+ // Up Arrow and Down Arrow keys.
+ if ( 38 === event.keyCode || 40 === event.keyCode ) {
clearInterval( wpLink.keyInterval );
event.preventDefault();
}
@@ -509,15 +605,6 @@
funcContext = this;
funcTriggered = true;
};
- },
-
- toggleInternalLinking: function( event ) {
- var visible = inputs.wrap.hasClass( 'search-panel-visible' );
-
- inputs.wrap.toggleClass( 'search-panel-visible', ! visible );
- setUserSetting( 'wplink', visible ? '0' : '1' );
- inputs[ ! visible ? 'search' : 'url' ].focus();
- event.preventDefault();
}
};
@@ -694,7 +781,7 @@
this.querying = true;
- $.post( ajaxurl, query, function( r ) {
+ $.post( window.ajaxurl, query, function( r ) {
self.page++;
self.querying = false;
self.allLoaded = ! r;
@@ -704,4 +791,4 @@
});
$( document ).ready( wpLink.init );
-})( jQuery );
+})( jQuery, window.wpLinkL10n, window.wp );