2015-08-04 17:42:26 -04:00
|
|
|
( function( tinymce ) {
|
2017-05-08 21:40:46 -04:00
|
|
|
tinymce.ui.Factory.add( 'WPLinkPreview', tinymce.ui.Control.extend( {
|
2015-06-24 19:05:26 -04:00
|
|
|
url: '#',
|
|
|
|
renderHtml: function() {
|
|
|
|
return (
|
|
|
|
'<div id="' + this._id + '" class="wp-link-preview">' +
|
2017-09-19 04:01:45 -04:00
|
|
|
'<a href="' + this.url + '" target="_blank" rel="noopener" tabindex="-1">' + this.url + '</a>' +
|
2015-06-24 19:05:26 -04:00
|
|
|
'</div>'
|
|
|
|
);
|
|
|
|
},
|
|
|
|
setURL: function( url ) {
|
|
|
|
var index, lastIndex;
|
|
|
|
|
|
|
|
if ( this.url !== url ) {
|
|
|
|
this.url = url;
|
|
|
|
|
|
|
|
url = window.decodeURIComponent( url );
|
|
|
|
|
|
|
|
url = url.replace( /^(?:https?:)?\/\/(?:www\.)?/, '' );
|
|
|
|
|
|
|
|
if ( ( index = url.indexOf( '?' ) ) !== -1 ) {
|
|
|
|
url = url.slice( 0, index );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( index = url.indexOf( '#' ) ) !== -1 ) {
|
|
|
|
url = url.slice( 0, index );
|
|
|
|
}
|
|
|
|
|
|
|
|
url = url.replace( /(?:index)?\.html$/, '' );
|
|
|
|
|
2015-06-25 00:42:28 -04:00
|
|
|
if ( url.charAt( url.length - 1 ) === '/' ) {
|
|
|
|
url = url.slice( 0, -1 );
|
2015-06-24 19:05:26 -04:00
|
|
|
}
|
|
|
|
|
2016-02-05 19:51:27 -05:00
|
|
|
// If nothing's left (maybe the URL was just a fragment), use the whole URL.
|
|
|
|
if ( url === '' ) {
|
|
|
|
url = this.url;
|
|
|
|
}
|
|
|
|
|
2020-01-28 19:45:18 -05:00
|
|
|
// If the URL is longer that 40 chars, concatenate the beginning (after the domain) and ending with '...'.
|
2015-06-25 00:42:28 -04:00
|
|
|
if ( url.length > 40 && ( index = url.indexOf( '/' ) ) !== -1 && ( lastIndex = url.lastIndexOf( '/' ) ) !== -1 && lastIndex !== index ) {
|
2020-01-28 19:45:18 -05:00
|
|
|
// If the beginning + ending are shorter that 40 chars, show more of the ending.
|
2015-06-25 00:42:28 -04:00
|
|
|
if ( index + url.length - lastIndex < 40 ) {
|
2016-02-20 16:36:25 -05:00
|
|
|
lastIndex = -( 40 - ( index + 1 ) );
|
2015-06-25 00:42:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
url = url.slice( 0, index + 1 ) + '\u2026' + url.slice( lastIndex );
|
2015-06-24 19:05:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
tinymce.$( this.getEl().firstChild ).attr( 'href', this.url ).text( url );
|
|
|
|
}
|
|
|
|
}
|
2017-05-08 21:40:46 -04:00
|
|
|
} ) );
|
2015-06-24 19:05:26 -04:00
|
|
|
|
2017-05-08 21:40:46 -04:00
|
|
|
tinymce.ui.Factory.add( 'WPLinkInput', tinymce.ui.Control.extend( {
|
2016-01-22 19:08:26 -05:00
|
|
|
renderHtml: function() {
|
|
|
|
return (
|
|
|
|
'<div id="' + this._id + '" class="wp-link-input">' +
|
2024-05-14 12:49:09 -04:00
|
|
|
'<label for="' + this._id + '_label">' + tinymce.translate( 'Paste URL or type to search' ) + '</label><input id="' + this._id + '_label" type="text" value="" />' +
|
2016-02-24 22:48:26 -05:00
|
|
|
'<input type="text" style="display:none" value="" />' +
|
2016-01-22 19:08:26 -05:00
|
|
|
'</div>'
|
|
|
|
);
|
|
|
|
},
|
|
|
|
setURL: function( url ) {
|
2024-05-14 12:49:09 -04:00
|
|
|
this.getEl().firstChild.nextSibling.value = url;
|
2016-02-24 01:20:26 -05:00
|
|
|
},
|
|
|
|
getURL: function() {
|
2024-05-14 12:49:09 -04:00
|
|
|
return tinymce.trim( this.getEl().firstChild.nextSibling.value );
|
2016-02-24 01:20:26 -05:00
|
|
|
},
|
|
|
|
getLinkText: function() {
|
2024-05-14 12:49:09 -04:00
|
|
|
var text = this.getEl().firstChild.nextSibling.nextSibling.value;
|
2016-02-26 19:52:26 -05:00
|
|
|
|
|
|
|
if ( ! tinymce.trim( text ) ) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
return text.replace( /[\r\n\t ]+/g, ' ' );
|
2016-02-24 01:20:26 -05:00
|
|
|
},
|
|
|
|
reset: function() {
|
2024-05-14 12:49:09 -04:00
|
|
|
var urlInput = this.getEl().firstChild.nextSibling;
|
2016-02-27 16:33:26 -05:00
|
|
|
|
2016-02-24 01:20:26 -05:00
|
|
|
urlInput.value = '';
|
|
|
|
urlInput.nextSibling.value = '';
|
2016-01-22 19:08:26 -05:00
|
|
|
}
|
2017-05-08 21:40:46 -04:00
|
|
|
} ) );
|
2016-01-22 19:08:26 -05:00
|
|
|
|
2015-08-04 17:42:26 -04:00
|
|
|
tinymce.PluginManager.add( 'wplink', function( editor ) {
|
|
|
|
var toolbar;
|
2016-01-22 19:08:26 -05:00
|
|
|
var editToolbar;
|
|
|
|
var previewInstance;
|
|
|
|
var inputInstance;
|
2016-02-27 16:33:26 -05:00
|
|
|
var linkNode;
|
2016-03-13 18:44:25 -04:00
|
|
|
var doingUndoRedo;
|
|
|
|
var doingUndoRedoTimer;
|
2016-01-22 19:08:26 -05:00
|
|
|
var $ = window.jQuery;
|
2016-07-20 23:42:34 -04:00
|
|
|
var emailRegex = /^(mailto:)?[a-z0-9._%+-]+@[a-z0-9][a-z0-9.-]*\.[a-z]{2,63}$/i;
|
2016-07-26 19:24:28 -04:00
|
|
|
var urlRegex1 = /^https?:\/\/([^\s/?.#-][^\s\/?.#]*\.?)+(\/[^\s"]*)?$/i;
|
|
|
|
var urlRegex2 = /^https?:\/\/[^\/]+\.[^\/]+($|\/)/i;
|
2016-07-20 23:42:34 -04:00
|
|
|
var speak = ( typeof window.wp !== 'undefined' && window.wp.a11y && window.wp.a11y.speak ) ? window.wp.a11y.speak : function() {};
|
|
|
|
var hasLinkError = false;
|
Script Loader: Switch to JavaScript translations.
Update JavaScript files for tag suggestions and the TinyMCE link plugin to use client side translations. This allows for `_n()` to be used for strings requiring singular and plural versions in which the correct form is only known client side.
Props audrasjb, chaion07, costdev, hellofromtonya, johnbillion, marybaum, nicolefurlan, oglekler, rebasaurus, rsiddharth, sergeybiryukov, shaampk1, shahariaazam, swissspidy, tobifjellner.
Fixes #48244.
Built from https://develop.svn.wordpress.org/trunk@57654
git-svn-id: http://core.svn.wordpress.org/trunk@57155 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2024-02-18 17:16:14 -05:00
|
|
|
var __ = window.wp.i18n.__;
|
|
|
|
var _n = window.wp.i18n._n;
|
|
|
|
var sprintf = window.wp.i18n.sprintf;
|
2016-01-22 19:08:26 -05:00
|
|
|
|
2016-02-05 19:51:27 -05:00
|
|
|
function getSelectedLink() {
|
2016-02-20 17:14:27 -05:00
|
|
|
var href, html,
|
2017-05-19 14:55:44 -04:00
|
|
|
node = editor.selection.getStart(),
|
2016-02-20 16:36:25 -05:00
|
|
|
link = editor.dom.getParent( node, 'a[href]' );
|
2016-02-05 19:51:27 -05:00
|
|
|
|
2016-02-20 16:36:25 -05:00
|
|
|
if ( ! link ) {
|
|
|
|
html = editor.selection.getContent({ format: 'raw' });
|
2016-02-05 19:51:27 -05:00
|
|
|
|
2016-02-20 16:36:25 -05:00
|
|
|
if ( html && html.indexOf( '</a>' ) !== -1 ) {
|
|
|
|
href = html.match( /href="([^">]+)"/ );
|
|
|
|
|
|
|
|
if ( href && href[1] ) {
|
|
|
|
link = editor.$( 'a[href="' + href[1] + '"]', node )[0];
|
|
|
|
}
|
2016-02-05 19:51:27 -05:00
|
|
|
|
2016-02-20 16:36:25 -05:00
|
|
|
if ( link ) {
|
|
|
|
editor.selection.select( link );
|
|
|
|
}
|
2016-02-05 19:51:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return link;
|
|
|
|
}
|
2016-02-20 17:14:27 -05:00
|
|
|
|
2016-02-20 16:36:25 -05:00
|
|
|
function removePlaceholders() {
|
|
|
|
editor.$( 'a' ).each( function( i, element ) {
|
|
|
|
var $element = editor.$( element );
|
|
|
|
|
|
|
|
if ( $element.attr( 'href' ) === '_wp_link_placeholder' ) {
|
|
|
|
editor.dom.remove( element, true );
|
2016-02-24 01:20:26 -05:00
|
|
|
} else if ( $element.attr( 'data-wplink-edit' ) ) {
|
|
|
|
$element.attr( 'data-wplink-edit', null );
|
2016-02-20 16:36:25 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2016-02-20 17:14:27 -05:00
|
|
|
|
2016-02-20 16:36:25 -05:00
|
|
|
function removePlaceholderStrings( content, dataAttr ) {
|
2016-06-17 16:41:28 -04:00
|
|
|
return content.replace( /(<a [^>]+>)([\s\S]*?)<\/a>/g, function( all, tag, text ) {
|
|
|
|
if ( tag.indexOf( ' href="_wp_link_placeholder"' ) > -1 ) {
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( dataAttr ) {
|
|
|
|
tag = tag.replace( / data-wplink-edit="true"/g, '' );
|
|
|
|
}
|
|
|
|
|
|
|
|
tag = tag.replace( / data-wplink-url-error="true"/g, '' );
|
|
|
|
|
|
|
|
return tag + text + '</a>';
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkLink( node ) {
|
|
|
|
var $link = editor.$( node );
|
|
|
|
var href = $link.attr( 'href' );
|
|
|
|
|
|
|
|
if ( ! href || typeof $ === 'undefined' ) {
|
|
|
|
return;
|
2016-02-20 16:36:25 -05:00
|
|
|
}
|
|
|
|
|
2016-07-20 23:42:34 -04:00
|
|
|
hasLinkError = false;
|
|
|
|
|
2016-07-26 19:24:28 -04:00
|
|
|
if ( /^http/i.test( href ) && ( ! urlRegex1.test( href ) || ! urlRegex2.test( href ) ) ) {
|
|
|
|
hasLinkError = true;
|
|
|
|
$link.attr( 'data-wplink-url-error', 'true' );
|
|
|
|
speak( editor.translate( 'Warning: the link has been inserted but may have errors. Please test it.' ), 'assertive' );
|
2016-06-17 16:41:28 -04:00
|
|
|
} else {
|
|
|
|
$link.removeAttr( 'data-wplink-url-error' );
|
|
|
|
}
|
2016-02-20 16:36:25 -05:00
|
|
|
}
|
2016-02-05 19:51:27 -05:00
|
|
|
|
2016-01-22 19:08:26 -05:00
|
|
|
editor.on( 'preinit', function() {
|
|
|
|
if ( editor.wp && editor.wp._createToolbar ) {
|
|
|
|
toolbar = editor.wp._createToolbar( [
|
|
|
|
'wp_link_preview',
|
|
|
|
'wp_link_edit',
|
|
|
|
'wp_link_remove'
|
|
|
|
], true );
|
|
|
|
|
2016-02-29 14:38:27 -05:00
|
|
|
var editButtons = [
|
2016-01-22 19:08:26 -05:00
|
|
|
'wp_link_input',
|
2016-02-29 14:38:27 -05:00
|
|
|
'wp_link_apply'
|
|
|
|
];
|
|
|
|
|
|
|
|
if ( typeof window.wpLink !== 'undefined' ) {
|
|
|
|
editButtons.push( 'wp_link_advanced' );
|
|
|
|
}
|
|
|
|
|
|
|
|
editToolbar = editor.wp._createToolbar( editButtons, true );
|
2016-01-22 19:08:26 -05:00
|
|
|
|
|
|
|
editToolbar.on( 'show', function() {
|
2016-06-03 00:54:27 -04:00
|
|
|
if ( typeof window.wpLink === 'undefined' || ! window.wpLink.modalOpen ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
window.setTimeout( function() {
|
2016-02-27 16:33:26 -05:00
|
|
|
var element = editToolbar.$el.find( 'input.ui-autocomplete-input' )[0],
|
|
|
|
selection = linkNode && ( linkNode.textContent || linkNode.innerText );
|
2016-02-26 19:52:26 -05:00
|
|
|
|
|
|
|
if ( element ) {
|
2016-02-27 16:33:26 -05:00
|
|
|
if ( ! element.value && selection && typeof window.wpLink !== 'undefined' ) {
|
|
|
|
element.value = window.wpLink.getUrlFromSelection( selection );
|
|
|
|
}
|
|
|
|
|
2016-03-13 18:44:25 -04:00
|
|
|
if ( ! doingUndoRedo ) {
|
|
|
|
element.focus();
|
|
|
|
element.select();
|
|
|
|
}
|
2016-02-26 19:52:26 -05:00
|
|
|
}
|
|
|
|
} );
|
2016-02-24 01:20:26 -05:00
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
} );
|
|
|
|
|
|
|
|
editToolbar.on( 'hide', function() {
|
2016-02-24 01:20:26 -05:00
|
|
|
if ( ! editToolbar.scrolling ) {
|
|
|
|
editor.execCommand( 'wp_link_cancel' );
|
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
} );
|
|
|
|
}
|
|
|
|
} );
|
2015-08-04 17:42:26 -04:00
|
|
|
|
|
|
|
editor.addCommand( 'WP_Link', function() {
|
2016-02-29 14:38:27 -05:00
|
|
|
if ( tinymce.Env.ie && tinymce.Env.ie < 10 && typeof window.wpLink !== 'undefined' ) {
|
|
|
|
window.wpLink.open( editor.id );
|
2016-02-24 01:20:26 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-27 16:33:26 -05:00
|
|
|
linkNode = getSelectedLink();
|
2016-02-26 19:52:26 -05:00
|
|
|
editToolbar.tempHide = false;
|
|
|
|
|
2019-01-24 06:21:50 -05:00
|
|
|
if ( ! linkNode ) {
|
2016-02-20 16:36:25 -05:00
|
|
|
removePlaceholders();
|
2016-01-22 19:08:26 -05:00
|
|
|
editor.execCommand( 'mceInsertLink', false, { href: '_wp_link_placeholder' } );
|
2016-02-24 01:20:26 -05:00
|
|
|
|
2016-02-27 16:33:26 -05:00
|
|
|
linkNode = editor.$( 'a[href="_wp_link_placeholder"]' )[0];
|
2016-02-26 19:52:26 -05:00
|
|
|
editor.nodeChanged();
|
2016-01-22 19:08:26 -05:00
|
|
|
}
|
2019-01-24 06:21:50 -05:00
|
|
|
|
|
|
|
editor.dom.setAttribs( linkNode, { 'data-wplink-edit': true } );
|
2016-01-22 19:08:26 -05:00
|
|
|
} );
|
|
|
|
|
|
|
|
editor.addCommand( 'wp_link_apply', function() {
|
|
|
|
if ( editToolbar.scrolling ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-27 16:33:26 -05:00
|
|
|
var href, text;
|
2016-01-22 19:08:26 -05:00
|
|
|
|
2016-02-24 01:20:26 -05:00
|
|
|
if ( linkNode ) {
|
|
|
|
href = inputInstance.getURL();
|
|
|
|
text = inputInstance.getLinkText();
|
|
|
|
editor.focus();
|
2016-01-22 19:08:26 -05:00
|
|
|
|
2017-09-19 04:01:45 -04:00
|
|
|
var parser = document.createElement( 'a' );
|
|
|
|
parser.href = href;
|
|
|
|
|
|
|
|
if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
|
|
|
|
href = '';
|
|
|
|
}
|
|
|
|
|
2016-02-24 01:20:26 -05:00
|
|
|
if ( ! href ) {
|
|
|
|
editor.dom.remove( linkNode, true );
|
|
|
|
return;
|
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
|
2016-07-20 23:42:34 -04:00
|
|
|
if ( ! /^(?:[a-z]+:|#|\?|\.|\/)/.test( href ) && ! emailRegex.test( href ) ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
href = 'http://' + href;
|
|
|
|
}
|
|
|
|
|
|
|
|
editor.dom.setAttribs( linkNode, { href: href, 'data-wplink-edit': null } );
|
|
|
|
|
|
|
|
if ( ! tinymce.trim( linkNode.innerHTML ) ) {
|
|
|
|
editor.$( linkNode ).text( text || href );
|
|
|
|
}
|
2016-06-17 16:41:28 -04:00
|
|
|
|
|
|
|
checkLink( linkNode );
|
2016-02-24 01:20:26 -05:00
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
|
2016-02-24 01:20:26 -05:00
|
|
|
inputInstance.reset();
|
2016-01-22 19:08:26 -05:00
|
|
|
editor.nodeChanged();
|
2016-03-13 20:53:26 -04:00
|
|
|
|
|
|
|
// Audible confirmation message when a link has been inserted in the Editor.
|
2016-07-20 23:42:34 -04:00
|
|
|
if ( typeof window.wpLinkL10n !== 'undefined' && ! hasLinkError ) {
|
|
|
|
speak( window.wpLinkL10n.linkInserted );
|
2016-03-13 20:53:26 -04:00
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
} );
|
|
|
|
|
|
|
|
editor.addCommand( 'wp_link_cancel', function() {
|
2019-01-24 06:21:50 -05:00
|
|
|
inputInstance.reset();
|
|
|
|
|
2016-02-25 19:21:26 -05:00
|
|
|
if ( ! editToolbar.tempHide ) {
|
|
|
|
removePlaceholders();
|
2016-02-24 01:20:26 -05:00
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
} );
|
2015-08-04 17:42:26 -04:00
|
|
|
|
2016-06-29 05:42:30 -04:00
|
|
|
editor.addCommand( 'wp_unlink', function() {
|
|
|
|
editor.execCommand( 'unlink' );
|
|
|
|
editToolbar.tempHide = false;
|
|
|
|
editor.execCommand( 'wp_link_cancel' );
|
|
|
|
} );
|
|
|
|
|
2020-01-28 19:45:18 -05:00
|
|
|
// WP default shortcuts.
|
2015-11-09 16:32:28 -05:00
|
|
|
editor.addShortcut( 'access+a', '', 'WP_Link' );
|
2016-06-29 05:42:30 -04:00
|
|
|
editor.addShortcut( 'access+s', '', 'wp_unlink' );
|
2020-01-28 19:45:18 -05:00
|
|
|
// The "de-facto standard" shortcut, see #27305.
|
2015-11-09 16:32:28 -05:00
|
|
|
editor.addShortcut( 'meta+k', '', 'WP_Link' );
|
2015-08-04 17:42:26 -04:00
|
|
|
|
|
|
|
editor.addButton( 'link', {
|
|
|
|
icon: 'link',
|
|
|
|
tooltip: 'Insert/edit link',
|
|
|
|
cmd: 'WP_Link',
|
|
|
|
stateSelector: 'a[href]'
|
|
|
|
});
|
|
|
|
|
|
|
|
editor.addButton( 'unlink', {
|
|
|
|
icon: 'unlink',
|
|
|
|
tooltip: 'Remove link',
|
|
|
|
cmd: 'unlink'
|
|
|
|
});
|
|
|
|
|
|
|
|
editor.addMenuItem( 'link', {
|
|
|
|
icon: 'link',
|
|
|
|
text: 'Insert/edit link',
|
|
|
|
cmd: 'WP_Link',
|
|
|
|
stateSelector: 'a[href]',
|
|
|
|
context: 'insert',
|
|
|
|
prependToContext: true
|
|
|
|
});
|
|
|
|
|
|
|
|
editor.on( 'pastepreprocess', function( event ) {
|
|
|
|
var pastedStr = event.content,
|
|
|
|
regExp = /^(?:https?:)?\/\/\S+$/i;
|
|
|
|
|
|
|
|
if ( ! editor.selection.isCollapsed() && ! regExp.test( editor.selection.getContent() ) ) {
|
|
|
|
pastedStr = pastedStr.replace( /<[^>]+>/g, '' );
|
|
|
|
pastedStr = tinymce.trim( pastedStr );
|
|
|
|
|
|
|
|
if ( regExp.test( pastedStr ) ) {
|
|
|
|
editor.execCommand( 'mceInsertLink', false, {
|
|
|
|
href: editor.dom.decode( pastedStr )
|
|
|
|
} );
|
|
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
2016-02-20 17:14:27 -05:00
|
|
|
|
2016-02-20 16:36:25 -05:00
|
|
|
// Remove any remaining placeholders on saving.
|
|
|
|
editor.on( 'savecontent', function( event ) {
|
|
|
|
event.content = removePlaceholderStrings( event.content, true );
|
|
|
|
});
|
2016-02-20 17:14:27 -05:00
|
|
|
|
2016-02-20 16:36:25 -05:00
|
|
|
// Prevent adding undo levels on inserting link placeholder.
|
|
|
|
editor.on( 'BeforeAddUndo', function( event ) {
|
2016-02-25 19:21:26 -05:00
|
|
|
if ( event.lastLevel && event.lastLevel.content && event.level.content &&
|
|
|
|
event.lastLevel.content === removePlaceholderStrings( event.level.content ) ) {
|
|
|
|
|
|
|
|
event.preventDefault();
|
2016-02-20 16:36:25 -05:00
|
|
|
}
|
|
|
|
});
|
2015-08-04 17:42:26 -04:00
|
|
|
|
2016-03-13 18:44:25 -04:00
|
|
|
// When doing undo and redo with keyboard shortcuts (Ctrl|Cmd+Z, Ctrl|Cmd+Shift+Z, Ctrl|Cmd+Y),
|
|
|
|
// set a flag to not focus the inline dialog. The editor has to remain focused so the users can do consecutive undo/redo.
|
|
|
|
editor.on( 'keydown', function( event ) {
|
2016-06-29 05:42:30 -04:00
|
|
|
if ( event.keyCode === 27 ) { // Esc
|
|
|
|
editor.execCommand( 'wp_link_cancel' );
|
|
|
|
}
|
|
|
|
|
2016-03-13 18:44:25 -04:00
|
|
|
if ( event.altKey || ( tinymce.Env.mac && ( ! event.metaKey || event.ctrlKey ) ) ||
|
|
|
|
( ! tinymce.Env.mac && ! event.ctrlKey ) ) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( event.keyCode === 89 || event.keyCode === 90 ) { // Y or Z
|
|
|
|
doingUndoRedo = true;
|
|
|
|
|
|
|
|
window.clearTimeout( doingUndoRedoTimer );
|
|
|
|
doingUndoRedoTimer = window.setTimeout( function() {
|
|
|
|
doingUndoRedo = false;
|
|
|
|
}, 500 );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
2015-08-04 17:42:26 -04:00
|
|
|
editor.addButton( 'wp_link_preview', {
|
|
|
|
type: 'WPLinkPreview',
|
|
|
|
onPostRender: function() {
|
2016-01-22 19:08:26 -05:00
|
|
|
previewInstance = this;
|
|
|
|
}
|
|
|
|
} );
|
2015-08-04 17:42:26 -04:00
|
|
|
|
2016-01-22 19:08:26 -05:00
|
|
|
editor.addButton( 'wp_link_input', {
|
|
|
|
type: 'WPLinkInput',
|
|
|
|
onPostRender: function() {
|
2016-02-24 01:20:26 -05:00
|
|
|
var element = this.getEl(),
|
2024-05-14 12:49:09 -04:00
|
|
|
input = element.firstChild.nextSibling,
|
2016-02-24 01:20:26 -05:00
|
|
|
$input, cache, last;
|
2015-08-04 17:42:26 -04:00
|
|
|
|
2016-01-22 19:08:26 -05:00
|
|
|
inputInstance = this;
|
2015-08-04 17:42:26 -04:00
|
|
|
|
2016-02-20 16:36:25 -05:00
|
|
|
if ( $ && $.ui && $.ui.autocomplete ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
$input = $( input );
|
|
|
|
|
|
|
|
$input.on( 'keydown', function() {
|
|
|
|
$input.removeAttr( 'aria-activedescendant' );
|
2016-01-22 19:08:26 -05:00
|
|
|
} )
|
|
|
|
.autocomplete( {
|
|
|
|
source: function( request, response ) {
|
|
|
|
if ( last === request.term ) {
|
|
|
|
response( cache );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( /^https?:/.test( request.term ) || request.term.indexOf( '.' ) !== -1 ) {
|
|
|
|
return response();
|
|
|
|
}
|
|
|
|
|
|
|
|
$.post( window.ajaxurl, {
|
|
|
|
action: 'wp-link-ajax',
|
|
|
|
page: 1,
|
|
|
|
search: request.term,
|
|
|
|
_ajax_linking_nonce: $( '#_ajax_linking_nonce' ).val()
|
|
|
|
}, function( data ) {
|
|
|
|
cache = data;
|
|
|
|
response( data );
|
|
|
|
}, 'json' );
|
|
|
|
|
|
|
|
last = request.term;
|
|
|
|
},
|
|
|
|
focus: function( event, ui ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
$input.attr( 'aria-activedescendant', 'mce-wp-autocomplete-' + ui.item.ID );
|
2016-03-13 20:53:26 -04:00
|
|
|
/*
|
|
|
|
* Don't empty the URL input field, when using the arrow keys to
|
|
|
|
* highlight items. See api.jqueryui.com/autocomplete/#event-focus
|
|
|
|
*/
|
2016-03-12 14:41:26 -05:00
|
|
|
event.preventDefault();
|
2016-01-22 19:08:26 -05:00
|
|
|
},
|
|
|
|
select: function( event, ui ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
$input.val( ui.item.permalink );
|
2024-05-14 12:49:09 -04:00
|
|
|
$( element.firstChild.nextSibling.nextSibling ).val( ui.item.title );
|
2016-03-13 20:53:26 -04:00
|
|
|
|
2016-07-20 23:42:34 -04:00
|
|
|
if ( 9 === event.keyCode && typeof window.wpLinkL10n !== 'undefined' ) {
|
2016-03-13 20:53:26 -04:00
|
|
|
// Audible confirmation message when a link has been selected.
|
2016-07-20 23:42:34 -04:00
|
|
|
speak( window.wpLinkL10n.linkSelected );
|
2016-03-13 20:53:26 -04:00
|
|
|
}
|
|
|
|
|
2016-01-22 19:08:26 -05:00
|
|
|
return false;
|
|
|
|
},
|
|
|
|
open: function() {
|
2016-02-24 01:20:26 -05:00
|
|
|
$input.attr( 'aria-expanded', 'true' );
|
2016-01-22 19:08:26 -05:00
|
|
|
editToolbar.blockHide = true;
|
|
|
|
},
|
|
|
|
close: function() {
|
2016-02-24 01:20:26 -05:00
|
|
|
$input.attr( 'aria-expanded', 'false' );
|
2016-01-22 19:08:26 -05:00
|
|
|
editToolbar.blockHide = false;
|
|
|
|
},
|
|
|
|
minLength: 2,
|
|
|
|
position: {
|
2016-02-24 01:20:26 -05:00
|
|
|
my: 'left top+2'
|
2016-03-02 15:06:26 -05:00
|
|
|
},
|
|
|
|
messages: {
|
Script Loader: Switch to JavaScript translations.
Update JavaScript files for tag suggestions and the TinyMCE link plugin to use client side translations. This allows for `_n()` to be used for strings requiring singular and plural versions in which the correct form is only known client side.
Props audrasjb, chaion07, costdev, hellofromtonya, johnbillion, marybaum, nicolefurlan, oglekler, rebasaurus, rsiddharth, sergeybiryukov, shaampk1, shahariaazam, swissspidy, tobifjellner.
Fixes #48244.
Built from https://develop.svn.wordpress.org/trunk@57654
git-svn-id: http://core.svn.wordpress.org/trunk@57155 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2024-02-18 17:16:14 -05:00
|
|
|
noResults: __( 'No results found.' ) ,
|
2016-03-02 15:06:26 -05:00
|
|
|
results: function( number ) {
|
Script Loader: Switch to JavaScript translations.
Update JavaScript files for tag suggestions and the TinyMCE link plugin to use client side translations. This allows for `_n()` to be used for strings requiring singular and plural versions in which the correct form is only known client side.
Props audrasjb, chaion07, costdev, hellofromtonya, johnbillion, marybaum, nicolefurlan, oglekler, rebasaurus, rsiddharth, sergeybiryukov, shaampk1, shahariaazam, swissspidy, tobifjellner.
Fixes #48244.
Built from https://develop.svn.wordpress.org/trunk@57654
git-svn-id: http://core.svn.wordpress.org/trunk@57155 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2024-02-18 17:16:14 -05:00
|
|
|
return sprintf(
|
|
|
|
/* translators: %d: Number of search results found. */
|
|
|
|
_n(
|
|
|
|
'%d result found. Use up and down arrow keys to navigate.',
|
|
|
|
'%d results found. Use up and down arrow keys to navigate.',
|
|
|
|
number
|
|
|
|
),
|
|
|
|
number
|
|
|
|
);
|
2016-03-02 15:06:26 -05:00
|
|
|
}
|
2015-08-04 17:42:26 -04:00
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
} ).autocomplete( 'instance' )._renderItem = function( ul, item ) {
|
2018-01-02 13:11:52 -05:00
|
|
|
var fallbackTitle = ( typeof window.wpLinkL10n !== 'undefined' ) ? window.wpLinkL10n.noTitle : '',
|
|
|
|
title = item.title ? item.title : fallbackTitle;
|
|
|
|
|
2016-01-22 19:08:26 -05:00
|
|
|
return $( '<li role="option" id="mce-wp-autocomplete-' + item.ID + '">' )
|
2018-01-02 13:11:52 -05:00
|
|
|
.append( '<span>' + title + '</span> <span class="wp-editor-float-right">' + item.info + '</span>' )
|
2016-01-22 19:08:26 -05:00
|
|
|
.appendTo( ul );
|
|
|
|
};
|
|
|
|
|
2016-02-24 01:20:26 -05:00
|
|
|
$input.attr( {
|
2016-01-22 19:08:26 -05:00
|
|
|
'role': 'combobox',
|
|
|
|
'aria-autocomplete': 'list',
|
|
|
|
'aria-expanded': 'false',
|
2016-02-24 01:20:26 -05:00
|
|
|
'aria-owns': $input.autocomplete( 'widget' ).attr( 'id' )
|
2016-03-13 20:53:26 -04:00
|
|
|
} )
|
2016-01-22 19:08:26 -05:00
|
|
|
.on( 'focus', function() {
|
2016-03-13 20:53:26 -04:00
|
|
|
var inputValue = $input.val();
|
|
|
|
/*
|
|
|
|
* Don't trigger a search if the URL field already has a link or is empty.
|
|
|
|
* Also, avoids screen readers announce `No search results`.
|
|
|
|
*/
|
|
|
|
if ( inputValue && ! /^https?:/.test( inputValue ) ) {
|
|
|
|
$input.autocomplete( 'search' );
|
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
} )
|
2016-04-17 07:09:28 -04:00
|
|
|
// Returns a jQuery object containing the menu element.
|
2016-01-22 19:08:26 -05:00
|
|
|
.autocomplete( 'widget' )
|
2016-02-24 01:20:26 -05:00
|
|
|
.addClass( 'wplink-autocomplete' )
|
2016-03-13 20:53:26 -04:00
|
|
|
.attr( 'role', 'listbox' )
|
2016-04-17 07:09:28 -04:00
|
|
|
.removeAttr( 'tabindex' ) // Remove the `tabindex=0` attribute added by jQuery UI.
|
|
|
|
/*
|
|
|
|
* Looks like Safari and VoiceOver need an `aria-selected` attribute. See ticket #33301.
|
|
|
|
* The `menufocus` and `menublur` events are the same events used to add and remove
|
|
|
|
* the `ui-state-focus` CSS class on the menu items. See jQuery UI Menu Widget.
|
|
|
|
*/
|
|
|
|
.on( 'menufocus', function( event, ui ) {
|
|
|
|
ui.item.attr( 'aria-selected', 'true' );
|
|
|
|
})
|
|
|
|
.on( 'menublur', function() {
|
|
|
|
/*
|
|
|
|
* The `menublur` event returns an object where the item is `null`
|
|
|
|
* so we need to find the active item with other means.
|
|
|
|
*/
|
|
|
|
$( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' );
|
|
|
|
});
|
2016-01-22 19:08:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
tinymce.$( input ).on( 'keydown', function( event ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
if ( event.keyCode === 13 ) {
|
|
|
|
editor.execCommand( 'wp_link_apply' );
|
2016-02-26 19:52:26 -05:00
|
|
|
event.preventDefault();
|
2016-02-24 01:20:26 -05:00
|
|
|
}
|
2015-08-04 17:42:26 -04:00
|
|
|
} );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
2016-01-22 19:08:26 -05:00
|
|
|
editor.on( 'wptoolbar', function( event ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
var linkNode = editor.dom.getParent( event.element, 'a' ),
|
2016-07-20 23:42:34 -04:00
|
|
|
$linkNode, href, edit;
|
2016-02-24 01:20:26 -05:00
|
|
|
|
2016-06-03 00:54:27 -04:00
|
|
|
if ( typeof window.wpLink !== 'undefined' && window.wpLink.modalOpen ) {
|
2016-02-25 19:21:26 -05:00
|
|
|
editToolbar.tempHide = true;
|
2016-02-24 01:20:26 -05:00
|
|
|
return;
|
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
|
2016-02-25 19:21:26 -05:00
|
|
|
editToolbar.tempHide = false;
|
|
|
|
|
2016-02-24 01:20:26 -05:00
|
|
|
if ( linkNode ) {
|
|
|
|
$linkNode = editor.$( linkNode );
|
|
|
|
href = $linkNode.attr( 'href' );
|
|
|
|
edit = $linkNode.attr( 'data-wplink-edit' );
|
2016-01-22 19:08:26 -05:00
|
|
|
|
|
|
|
if ( href === '_wp_link_placeholder' || edit ) {
|
2016-04-22 15:11:28 -04:00
|
|
|
if ( href !== '_wp_link_placeholder' && ! inputInstance.getURL() ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
inputInstance.setURL( href );
|
|
|
|
}
|
|
|
|
|
|
|
|
event.element = linkNode;
|
2016-01-22 19:08:26 -05:00
|
|
|
event.toolbar = editToolbar;
|
2016-02-24 01:20:26 -05:00
|
|
|
} else if ( href && ! $linkNode.find( 'img' ).length ) {
|
2016-01-22 19:08:26 -05:00
|
|
|
previewInstance.setURL( href );
|
2016-02-24 01:20:26 -05:00
|
|
|
event.element = linkNode;
|
2016-01-22 19:08:26 -05:00
|
|
|
event.toolbar = toolbar;
|
2016-06-17 16:41:28 -04:00
|
|
|
|
|
|
|
if ( $linkNode.attr( 'data-wplink-url-error' ) === 'true' ) {
|
2016-07-20 23:42:34 -04:00
|
|
|
toolbar.$el.find( '.wp-link-preview a' ).addClass( 'wplink-url-error' );
|
2016-06-17 16:41:28 -04:00
|
|
|
} else {
|
2016-07-20 23:42:34 -04:00
|
|
|
toolbar.$el.find( '.wp-link-preview a' ).removeClass( 'wplink-url-error' );
|
|
|
|
hasLinkError = false;
|
2016-06-17 16:41:28 -04:00
|
|
|
}
|
2016-01-22 19:08:26 -05:00
|
|
|
}
|
2016-06-30 11:18:27 -04:00
|
|
|
} else if ( editToolbar.visible() ) {
|
2016-06-29 05:42:30 -04:00
|
|
|
editor.execCommand( 'wp_link_cancel' );
|
2016-01-22 19:08:26 -05:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
2015-08-04 17:42:26 -04:00
|
|
|
editor.addButton( 'wp_link_edit', {
|
2020-01-28 19:45:18 -05:00
|
|
|
tooltip: 'Edit|button', // '|button' is not displayed, only used for context.
|
2015-08-04 17:42:26 -04:00
|
|
|
icon: 'dashicon dashicons-edit',
|
|
|
|
cmd: 'WP_Link'
|
|
|
|
} );
|
|
|
|
|
|
|
|
editor.addButton( 'wp_link_remove', {
|
2016-10-24 17:59:22 -04:00
|
|
|
tooltip: 'Remove link',
|
|
|
|
icon: 'dashicon dashicons-editor-unlink',
|
2016-06-29 05:42:30 -04:00
|
|
|
cmd: 'wp_unlink'
|
2015-08-04 17:42:26 -04:00
|
|
|
} );
|
|
|
|
|
2016-01-22 19:08:26 -05:00
|
|
|
editor.addButton( 'wp_link_advanced', {
|
2016-03-15 22:04:27 -04:00
|
|
|
tooltip: 'Link options',
|
2016-01-22 19:08:26 -05:00
|
|
|
icon: 'dashicon dashicons-admin-generic',
|
|
|
|
onclick: function() {
|
2016-02-20 16:36:25 -05:00
|
|
|
if ( typeof window.wpLink !== 'undefined' ) {
|
2016-02-24 01:20:26 -05:00
|
|
|
var url = inputInstance.getURL() || null,
|
|
|
|
text = inputInstance.getLinkText() || null;
|
2016-02-20 16:36:25 -05:00
|
|
|
|
2019-01-24 06:21:50 -05:00
|
|
|
window.wpLink.open( editor.id, url, text );
|
2016-03-13 20:53:26 -04:00
|
|
|
|
2017-05-11 19:04:40 -04:00
|
|
|
editToolbar.tempHide = true;
|
2019-01-24 06:21:50 -05:00
|
|
|
editToolbar.hide();
|
2016-02-20 16:36:25 -05:00
|
|
|
}
|
2015-08-25 00:38:20 -04:00
|
|
|
}
|
2015-08-04 17:42:26 -04:00
|
|
|
} );
|
2016-01-22 19:08:26 -05:00
|
|
|
|
|
|
|
editor.addButton( 'wp_link_apply', {
|
|
|
|
tooltip: 'Apply',
|
|
|
|
icon: 'dashicon dashicons-editor-break',
|
|
|
|
cmd: 'wp_link_apply',
|
|
|
|
classes: 'widget btn primary'
|
|
|
|
} );
|
2016-02-24 22:48:26 -05:00
|
|
|
|
|
|
|
return {
|
2016-02-25 19:21:26 -05:00
|
|
|
close: function() {
|
|
|
|
editToolbar.tempHide = false;
|
|
|
|
editor.execCommand( 'wp_link_cancel' );
|
2016-06-17 16:41:28 -04:00
|
|
|
},
|
|
|
|
checkLink: checkLink
|
2016-02-24 22:48:26 -05:00
|
|
|
};
|
2015-06-24 19:05:26 -04:00
|
|
|
} );
|
2015-08-04 17:42:26 -04:00
|
|
|
} )( window.tinymce );
|